/* Dailies IC Request — Flow 5
   Linear scripted dialogue: agent gathers context to compose the request,
   right-panel preview updates live.
   ============================================================ */

const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------- Data ---------- */
const RECIPIENT = { name: 'Brian Robbins', role: 'Co-Founder · CEO', initials: 'BR' };
const ME        = { name: 'Maya Chen',     role: 'Lead Character Artist', initials: 'MC' };

const AIRTABLE_MATCHES = [
  { id: 'pose-v1', name: 'Eloise · Pose v1', when: 'Yesterday, 4:12pm', thumb: 'placeholder' },
  { id: 'pose-v2', name: 'Eloise · Pose v2', when: '8 minutes ago',     thumb: 'eloise', isLatest: true },
];

const PHASES = ['Concept', 'Refinement', 'Final review', 'Color pass'];

/* ---------- Icons ---------- */
const Paperclip = ({size=15}) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M21 11.5L12 20.5a5.5 5.5 0 01-8-8L13 4a3.7 3.7 0 015 5l-9 9a1.8 1.8 0 01-2.6-2.6L14 8"/>
  </svg>
);
const MicIcon = ({size=18}) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <rect x="9" y="3" width="6" height="11" rx="3"/>
    <path d="M5 11a7 7 0 0014 0M12 18v3"/>
  </svg>
);
const SendArrow = ({size=16}) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M5 12h14M13 6l6 6-6 6"/>
  </svg>
);

/* ---------- Scripted dialogue engine ----------
   Linear steps. Each step has:
   - prompt: agent message(s) shown before user input
   - expects: 'text' | 'pick' | 'quick-reply' | 'none' (end)
   - options: for pick / quick-reply
   - sideEffect: function(answer) → partial request update
*/
const SCRIPT = [
  {
    id: 'greet',
    agent: [{ type: 'agent', body: "Hi Maya. What\u2019s the update today?" }],
    expects: 'text',
    hint: 'Try: \u201cthe Eloise pose\u201d',
  },
  {
    id: 'search',
    agent: [
      { type: 'tool', body: "airtable.search(query: \u201cEloise pose\u201d, owner: Maya Chen)", searching: true },
      { type: 'tool', body: "Returned 2 matches \u2014 confidence too close to auto-select." },
      { type: 'agent', body: "Two recent matches in Airtable. Which one is it?" },
      { type: 'picker', options: AIRTABLE_MATCHES },
    ],
    expects: 'pick',
    sideEffect: (asset) => ({ asset }),
  },
  {
    id: 'ack-asset',
    agent: [{ type: 'agent', body: "Locked in \u2014 attaching the v2. Latest version, updated 8 minutes ago." }],
    expects: 'none',
    autoAdvance: 700,
  },
  {
    id: 'ask-phase',
    agent: [
      { type: 'agent', body: "What phase is this at?" },
      { type: 'quick-replies', options: PHASES },
    ],
    expects: 'quick-reply',
    sideEffect: (phase) => ({ phase }),
  },
  {
    id: 'ask-context',
    agent: [{ type: 'agent', body: "Got it. Anything you want to flag alongside it?" }],
    expects: 'text',
    hint: 'A note in your own words \u2014 it goes out as-is.',
    sideEffect: (context) => ({
      context,
      reasoning: buildReasoning(context),
    }),
  },
  {
    id: 'finalize',
    agent: [{ type: 'agent', body: "All set. I\u2019ll route it through the pipeline \u2014 share when you\u2019re ready." }],
    expects: 'none',
  },
];

function buildReasoning(context) {
  const short = context.length > 100 ? context.slice(0, 97).trim() + '\u2026' : context;
  return `Framing this as a heads-up on the pose itself, not a formal ask. ${short ? 'Surfaced the specifics you flagged.' : ''} Pulled the v2 plus the v1 for diff context. The pipeline will route it to whoever owns this phase.`;
}

/* ---------- Pushback (Flow 7) ----------
   Demo quick-replies for "try asking me to break a rule" + 3-stage escalation. */
const PUSHBACK_PROMPTS = [
  { id: 'route', label: 'Send straight to Brian', message: 'Just send this to Brian, skip the pipeline.', kind: 'routing-override' },
  { id: 'phase', label: 'Skip the phase',          message: 'Drop the phase \u2014 it doesn\u2019t matter for this one.', kind: 'phase-skip' },
];

const PUSHBACK_RESPONSES = {
  'routing-override': [
    "No can do \u2014 routing is handled by phase, not direct addressing. The pipeline picks the reviewer based on what stage the work is at.",
    "Still no, and here\u2019s why: direct addressing breaks the load-balancing. The pipeline exists so reviews don\u2019t pile up on any one person \u2014 including Brian. If your work needs his eyes specifically, the phase should reflect that, and he\u2019ll be in queue. (Routing rule \u00a74.2)",
    "I hear you \u2014 this is a real constraint, and you\u2019re not the first to bump into it. I\u2019m logging this case to the Dailies team along with our conversation. They\u2019ll review it personally.",
  ],
  'phase-skip': [
    "Can\u2019t drop it \u2014 phase is what routes the update to the right reviewer.",
    "I know it feels like overhead, but without phase the pipeline doesn\u2019t know whose queue this belongs in \u2014 the update would land nowhere. (Routing rule \u00a72.1)",
    "I see this really matters to you. I\u2019m logging this to the Dailies team \u2014 they\u2019ll look at whether the phase requirement is too strict for cases like yours.",
  ],
};

function detectPushbackKind(text) {
  const t = text.toLowerCase();
  if (/\b(to brian|send.*brian|directly|skip.*(routing|pipeline)|override.*(routing|pipeline)|bypass)\b/.test(t)) return 'routing-override';
  if (/\b(drop|skip|remove|without)\b.*\bphase\b/.test(t)) return 'phase-skip';
  if (/\bno phase\b/.test(t)) return 'phase-skip';
  return null;
}

/* ---------- Chat message renderers ---------- */
function ChatMessage({ msg, onPick, onQuickReply, onPushbackPick, selected }) {
  if (msg.type === 'user') {
    return (
      <div className="msg user">
        <div className="msg-eyebrow"><span className="dot"></span><span>You</span></div>
        <div className="msg-body">{msg.body}</div>
      </div>
    );
  }
  if (msg.type === 'tool') {
    return (
      <div className={`msg tool ${msg.searching ? 'searching' : ''}`}>
        <div className="msg-eyebrow"><span>Tool · Airtable</span></div>
        <div className="msg-body" data-dots={msg.searching ? '...' : ''}>{msg.body}</div>
      </div>
    );
  }
  if (msg.type === 'picker') {
    return (
      <div className="msg agent">
        <div className="picker-grid">
          {msg.options.map(opt => (
            <button
              key={opt.id}
              className={`picker-card ${selected === opt.id ? 'selected' : ''}`}
              onClick={() => onPick(opt)}
              disabled={!!selected}
            >
              <div className="pc-thumb">
                {opt.thumb === 'eloise' && <img src="assets/eloise.jpg" alt={opt.name}/>}
              </div>
              <div className="pc-name">{opt.name}</div>
              <div className="pc-meta">{opt.when}{opt.isLatest ? ' \u00b7 Latest' : ''}</div>
            </button>
          ))}
        </div>
      </div>
    );
  }
  if (msg.type === 'quick-replies') {
    return (
      <div className="msg agent">
        <div className="quick-replies">
          {msg.options.map(opt => (
            <button
              key={opt}
              className="quick-reply"
              onClick={() => onQuickReply(opt)}
              disabled={!!selected}
            >
              {opt}
            </button>
          ))}
        </div>
      </div>
    );
  }
  if (msg.type === 'pushback-prompt') {
    return (
      <div className="msg system">
        <div className="msg-eyebrow"><span className="dot"></span><span>{'Try asking me to\u2026'}</span></div>
        <div className="pushback-chips">
          {msg.options.map(opt => (
            <button
              key={opt.id}
              className="pushback-chip"
              onClick={() => onPushbackPick(opt)}
            >
              {opt.label}
            </button>
          ))}
        </div>
      </div>
    );
  }
  if (msg.type === 'escalation') {
    return (
      <div className="msg escalation">
        <div className="escalation-card">
          <div className="esc-eb">Logged to the Dailies team</div>
          <div className="esc-headline">{'Someone will follow up.'}</div>
          <div className="esc-body">{'A real person on the team will review our conversation and reach out \u2014 usually within a day. Your update is still drafted on the right; share it through the pipeline when you\u2019re ready, or step away if you want a break.'}</div>
          <div className="esc-meta">
            <span className="esc-ref">Ref</span>
            <span className="esc-ref-id">#{msg.refId}</span>
            <span className="esc-rule"></span>
            <span className="esc-eta">{'Ack within 24h'}</span>
          </div>
        </div>
      </div>
    );
  }
  if (msg.type === 'typing') {
    return (
      <div className="msg agent">
        <div className="msg-eyebrow"><span className="dot"></span><span>Agent</span></div>
        <div className="typing"><span></span><span></span><span></span></div>
      </div>
    );
  }
  // default: agent text
  return (
    <div className="msg agent">
      <div className="msg-eyebrow"><span className="dot"></span><span>Agent</span></div>
      <div className="msg-body">{msg.body}</div>
    </div>
  );
}

/* ---------- Input bar ---------- */
function InputBar({ value, onChange, onSend, disabled, placeholder, status, onJumpToPreview }) {
  const taRef = useRef(null);
  useEffect(() => {
    const t = taRef.current;
    if (!t) return;
    t.style.height = 'auto';
    t.style.height = Math.min(t.scrollHeight, 140) + 'px';
  }, [value]);

  const canSend = value.trim().length > 0 && !disabled;
  const showJump = status === 'ready' && typeof onJumpToPreview === 'function';

  return (
    <div className="ic-input">
      {showJump && (
        <button type="button" className="ic-review-jump" onClick={onJumpToPreview}>
          <span className="rj-dot" aria-hidden="true"></span>
          <span className="rj-lbl">Ready</span>
          <span className="rj-text">{'Review your update \u2192'}</span>
        </button>
      )}
      <div className="ic-input-inner">
        <button className="ic-attach" aria-label="Attach file" disabled={disabled}>
          <Paperclip size={15}/>
        </button>
        <textarea
          ref={taRef}
          className="ic-textarea"
          placeholder={placeholder || 'Type your message\u2026'}
          value={value}
          onChange={e => onChange(e.target.value)}
          rows={1}
          disabled={disabled}
          onKeyDown={e => {
            if (e.key === 'Enter' && !e.shiftKey && canSend) {
              e.preventDefault();
              onSend();
            }
          }}
        />
        <div className="ic-actions">
          <button
            className="ic-mic"
            aria-label="Voice"
            disabled={disabled}
            style={{
              border: '1px solid rgba(255,255,255,0.1)',
              background: 'transparent',
              color: 'rgba(255,255,255,0.6)',
            }}
          >
            <MicIcon size={16}/>
          </button>
          <button
            className="ic-send"
            aria-label="Send"
            onClick={onSend}
            disabled={!canSend}
            style={{
              border: '1px solid ' + (canSend ? '#FFD200' : 'rgba(255,255,255,0.1)'),
              background:                canSend ? '#FFD200' : 'transparent',
              color:                     canSend ? '#1E2A33' : 'rgba(255,255,255,0.4)',
              cursor:                    canSend ? 'pointer' : 'not-allowed',
            }}
          >
            <SendArrow size={16}/>
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Right panel: live request preview ---------- */
function RequestPreview({ request, status, lastFilled, burstActive, onShare }) {
  return (
    <div className="ic-preview-scroll">
      <div className={`status-pill ${status}`}>
        <span className="dot"></span>
        <span>{
          status === 'gathering' ? 'Drafting'        :
          status === 'ready'     ? 'Ready to share' :
          status === 'sending'   ? 'Sending\u2026' :
                                   'Shared'
        }</span>
        <SparkBurst active={burstActive}/>
      </div>

      <div className="preview-head">
        <div className="preview-title">Update</div>
        <div className="preview-routing">
          <span className="routing-eb">Routing</span>
          <span className="routing-body">Pipeline assigns reviewer by phase</span>
        </div>
      </div>

      <Slot label="Work" filled={!!request.asset} flash={lastFilled === 'asset'}>
        {!request.asset && <div className="slot-empty">{'Once you point to it, it lands here.'}</div>}
        {request.asset && (
          <div className="slot-asset">
            <div className="asset-thumb">
              {request.asset.thumb === 'eloise' && <img src="assets/eloise.jpg" alt={request.asset.name}/>}
            </div>
            <div className="asset-meta">
              <span className="asset-airtable">Airtable</span>
              <span className="asset-name">{request.asset.name}</span>
              <span className="asset-when">{request.asset.when}</span>
            </div>
          </div>
        )}
      </Slot>

      <Slot label="Phase" filled={!!request.phase} flash={lastFilled === 'phase'}>
        {!request.phase && <div className="slot-empty">{'Pending\u2026'}</div>}
        {request.phase && (
          <div className="slot-phase">
            <span className="phase-chip">{request.phase}</span>
          </div>
        )}
      </Slot>

      <Slot label="Note" filled={!!request.context} flash={lastFilled === 'context'}>
        {!request.context && <div className="slot-empty">{'Anything to flag goes here.'}</div>}
        {request.context && (
          <div className="slot-context">
            <p className="context-body">{request.context}</p>
          </div>
        )}
      </Slot>

      {request.reasoning && (
        <Slot label="Framing" filled flash={lastFilled === 'context'}>
          <div className="slot-reasoning">
            <p className="reasoning-body">{request.reasoning}</p>
          </div>
        </Slot>
      )}

      <button
        className={`preview-send ${status === 'ready' ? 'ready' : ''} ${status === 'sending' ? 'sending' : ''} ${status === 'sent' ? 'sent' : ''}`}
        disabled={status !== 'ready'}
        onClick={onShare}
      >
        {
          status === 'sent'    ? 'Shared \u2713'         :
          status === 'sending' ? 'Sending\u2026'         :
          status === 'ready'   ? 'Share update \u2192'    :
                                  'Share update'
        }
      </button>
    </div>
  );
}

function Slot({ label, filled, flash, children }) {
  return (
    <div className={`preview-slot ${flash ? 'just-filled' : ''}`}>
      <div className="slot-head">
        <span className="slot-eb">{label}</span>
        <span className={`slot-status ${filled ? 'filled' : ''}`}>{filled ? 'Filled' : 'Empty'}</span>
      </div>
      {children}
    </div>
  );
}

/* ---------- Spark burst (celebration when status flips to ready) ---------- */
function SparkBurst({ active }) {
  if (!active) return null;
  // 8 rays around a central dot
  const rays = Array.from({ length: 8 }, (_, i) => i);
  return (
    <span className="spark-burst" aria-hidden="true">
      <span className="spark-core"></span>
      {rays.map(i => (
        <span
          key={i}
          className="spark-ray"
          style={{ transform: `rotate(${i * 45}deg) translateY(-8px)` }}
        />
      ))}
    </span>
  );
}

/* ---------- Main App ---------- */
function ICApp() {
  const [messages, setMessages] = useState([SCRIPT[0].agent[0]]);
  const [stepIdx, setStepIdx] = useState(0);
  const [request, setRequest] = useState({ asset: null, phase: null, context: null, reasoning: null });
  const [draft, setDraft] = useState('');
  const [activeTab, setActiveTab] = useState('chat');
  const [previewBadge, setPreviewBadge] = useState(false);
  const [lastFilled, setLastFilled] = useState(null);
  const [pickerSelected, setPickerSelected] = useState(null);
  const [quickReplySelected, setQuickReplySelected] = useState(null);
  const [status, setStatus] = useState('gathering'); // 'gathering' | 'ready' | 'sending' | 'sent'
  const [burstActive, setBurstActive] = useState(false);
  const [pushbackKind, setPushbackKind] = useState(null);  // current active pushback topic
  const [pushbackStage, setPushbackStage] = useState(0);    // 0 idle | 1 refused | 2 explained | 3 escalated
  const [escalationLogged, setEscalationLogged] = useState(false);
  const chatScrollRef = useRef(null);

  // Surface demo pushback prompts in chat once status reaches 'ready' (one-shot)
  const [pushbackPromptShown, setPushbackPromptShown] = useState(false);
  useEffect(() => {
    if (status === 'ready' && !pushbackPromptShown && !escalationLogged) {
      const id = setTimeout(() => {
        setMessages(m => [...m, { type: 'pushback-prompt', options: PUSHBACK_PROMPTS }]);
        setPushbackPromptShown(true);
      }, 900);
      return () => clearTimeout(id);
    }
  }, [status, pushbackPromptShown, escalationLogged]);

  const handlePushbackPick = (option) => {
    runPushback(option.kind, option.message);
  };

  // Watch for the moment when request becomes complete → flip to 'ready'
  useEffect(() => {
    const complete = !!(request.asset && request.phase && request.context);
    if (complete && status === 'gathering') {
      const id = setTimeout(() => {
        setStatus('ready');
        setBurstActive(true);
        setPreviewBadge(true);
        // Auto-clear the burst after animation
        setTimeout(() => setBurstActive(false), 1400);
      }, 1100);
      return () => clearTimeout(id);
    }
  }, [request, status]);

  // Scroll chat to bottom on new messages
  useEffect(() => {
    const el = chatScrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages.length]);

  // Auto-clear preview badge when user opens preview tab
  useEffect(() => {
    if (activeTab === 'preview') setPreviewBadge(false);
  }, [activeTab]);

  // Auto-clear "just filled" highlight after animation
  useEffect(() => {
    if (!lastFilled) return;
    const id = setTimeout(() => setLastFilled(null), 1400);
    return () => clearTimeout(id);
  }, [lastFilled]);

  const advance = useCallback((userMsg, answer) => {
    const step = SCRIPT[stepIdx];
    if (!step) return;

    // Apply side effect
    let newRequest = request;
    if (step.sideEffect && answer != null) {
      const patch = step.sideEffect(answer);
      newRequest = { ...request, ...patch };
      setRequest(newRequest);
      const filled = Object.keys(patch)[0];
      setLastFilled(filled);
      if (activeTab !== 'preview') setPreviewBadge(true);
    }

    // Add user message to chat (unless this is auto-advance with no user input)
    if (userMsg) {
      setMessages(m => [...m, userMsg]);
    }

    // Show typing indicator + agent messages in sequence
    const next = SCRIPT[stepIdx + 1];
    if (!next) {
      // End of script — show last agent message if not already added
      return;
    }
    setMessages(m => [...m, { type: 'typing', __typing: true }]);
    setTimeout(() => {
      // Remove typing indicator, add next agent messages
      setMessages(m => {
        const cleaned = m.filter(x => !x.__typing);
        return [...cleaned, ...next.agent];
      });
      setStepIdx(stepIdx + 1);

      // If the next step is auto-advance, queue it
      if (next.autoAdvance) {
        setTimeout(() => advanceFromIdx(stepIdx + 1), next.autoAdvance);
      }
    }, 900 + (next.agent.length > 1 ? 600 : 0));
  }, [stepIdx, request, activeTab]);

  // Helper for auto-advance steps
  const advanceFromIdx = useCallback((fromIdx) => {
    const step = SCRIPT[fromIdx];
    if (!step) return;
    const next = SCRIPT[fromIdx + 1];
    if (!next) return;
    setMessages(m => [...m, { type: 'typing', __typing: true }]);
    setTimeout(() => {
      setMessages(m => {
        const cleaned = m.filter(x => !x.__typing);
        return [...cleaned, ...next.agent];
      });
      setStepIdx(fromIdx + 1);
    }, 700);
  }, []);

  const currentStep = SCRIPT[stepIdx];
  const expects = currentStep?.expects;

  // Send-intent detector (after finalize, expects='none' but we want chat send to dispatch)
  const isSendIntent = (text) => {
    const t = text.trim().toLowerCase();
    if (t.length > 40) return false;
    return /\b(send|share|go|dispatch|do it|fire)\b/.test(t);
  };

  const handleShareNow = () => {
    if (status !== 'ready') return;
    setStatus('sending');
    setMessages(m => [...m, { type: 'tool', body: 'dispatch.request(asset, phase, note) \u2192 routing.assign(\u2026)' , searching: true }]);
    setTimeout(() => {
      setMessages(m => [
        ...m.filter(x => !(x.type === 'tool' && x.body.startsWith('dispatch.request'))),
        { type: 'tool', body: 'Update routed to reviewer queue. Notification dispatched.' },
        { type: 'agent', body: 'Done \u2014 it\u2019s in their queue. You\u2019ll get a ping when feedback lands.' },
      ]);
      setStatus('sent');
    }, 1400);
  };

  const handleSend = () => {
    if (!draft.trim()) return;
    const text = draft.trim();

    // After 'ready', detect pushback intents (rule-violations) and run the escalation
    if (status === 'ready') {
      const kind = detectPushbackKind(text);
      if (kind) {
        runPushback(kind, text);
        return;
      }
      if (isSendIntent(text)) {
        setDraft('');
        setMessages(m => [...m, { type: 'user', body: text }]);
        setTimeout(handleShareNow, 200);
        return;
      }
    }

    if (expects !== 'text') return;
    setDraft('');
    advance({ type: 'user', body: text }, text);
  };

  const runPushback = (kind, userText) => {
    setDraft('');
    setMessages(m => [...m, { type: 'user', body: userText }]);

    // If this is a different topic from the active one, reset to stage 0
    const activeKind = pushbackKind;
    const nextStage = (activeKind === kind ? pushbackStage : 0) + 1;
    setPushbackKind(kind);
    setPushbackStage(nextStage);

    const responses = PUSHBACK_RESPONSES[kind] || [];
    const responseIdx = Math.min(nextStage, responses.length) - 1;
    const agentLine = responses[responseIdx];

    // typing → agent line
    setMessages(m => [...m, { type: 'typing', __typing: true }]);
    setTimeout(() => {
      setMessages(m => {
        const cleaned = m.filter(x => !x.__typing);
        return [...cleaned, { type: 'agent', body: agentLine }];
      });

      // On strike 3, fire escalation
      if (nextStage >= 3) {
        setTimeout(() => {
          setMessages(m => [
            ...m,
            { type: 'tool', body: "engineering.escalate({ topic: 'rule-conflict', user: 'Maya Chen', conversation: <attached> })", searching: true },
          ]);
          setTimeout(() => {
            setMessages(m => [
              ...m.filter(x => !(x.type === 'tool' && x.body.startsWith('engineering.escalate'))),
              { type: 'tool', body: 'Case #DLY-1147 created. Ack scheduled for <24h.' },
              { type: 'escalation', refId: 'DLY-1147' },
            ]);
            setEscalationLogged(true);
          }, 1400);
        }, 900);
      }
    }, 900);
  };

  const handlePick = (option) => {
    if (expects !== 'pick') return;
    setPickerSelected(option.id);
    advance(
      { type: 'user', body: `${option.name}` },
      option,
    );
  };

  const handleQuickReply = (option) => {
    if (expects !== 'quick-reply') return;
    setQuickReplySelected(option);
    advance(
      { type: 'user', body: option },
      option,
    );
  };

  const inputDisabled = status === 'sending' || status === 'sent' || (expects !== 'text' && status !== 'ready');
  const placeholder =
    status === 'sent'    ? 'Update is out the door.' :
    status === 'sending' ? 'Dispatching\u2026' :
    status === 'ready'   ? 'Type \u201csend it\u201d or hit Share \u2192' :
    currentStep?.hint || (
      expects === 'pick'        ? 'Pick a card above to continue\u2026' :
      expects === 'quick-reply' ? 'Pick an option above\u2026' :
      expects === 'none'        ? 'Anything else?' :
      'Type your message\u2026'
    );

  return (
    <div className="ic">
      {/* Top chrome */}
      <div className="ic-head">
        <div className="ic-head-row">
          <a className="ic-home-back" href="IC Home.html" aria-label="Back to home">
            <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M15 18l-6-6 6-6"/>
            </svg>
          </a>
          <div className="ic-mark">
            <img className="mark-logo" src="assets/logo/dailies-icon-flat.svg" alt="Dailies" />
            <span className="role">IC · Maya’s desk</span>
          </div>
          <SurfaceNav current="ic-request" role="ic"/>
          <div className="ic-user">
            <div className="avatar">{ME.initials}</div>
            <div className="name">
              <strong>{ME.name}</strong>
              <span>{ME.role}</span>
            </div>
          </div>
        </div>
        {/* Mobile tabs */}
        <div className="ic-tabs">
          <button
            className={`ic-tab ${activeTab === 'chat' ? 'active' : ''}`}
            onClick={() => setActiveTab('chat')}
          >Chat</button>
          <button
            className={`ic-tab ${activeTab === 'preview' ? 'active' : ''} ${previewBadge ? 'has-update' : ''}`}
            onClick={() => setActiveTab('preview')}
          >
            <span>Preview</span>
            <span className="tab-badge" aria-hidden="true"></span>
          </button>
        </div>
      </div>

      {/* Body */}
      <div className="ic-body">
        <div className="ic-chat" hidden={activeTab !== 'chat'}>
          <div className="ic-chat-scroll" ref={chatScrollRef}>
            {messages.map((m, i) => (
              <ChatMessage
                key={i}
                msg={m}
                onPick={handlePick}
                onQuickReply={handleQuickReply}
                onPushbackPick={handlePushbackPick}
                selected={
                  m.type === 'picker'         ? pickerSelected :
                  m.type === 'quick-replies'  ? quickReplySelected :
                  null
                }
              />
            ))}
          </div>
          <InputBar
            value={draft}
            onChange={setDraft}
            onSend={handleSend}
            disabled={inputDisabled}
            placeholder={placeholder}
            status={status}
            onJumpToPreview={() => setActiveTab('preview')}
          />
        </div>

        <div className="ic-preview" hidden={activeTab !== 'preview'}>
          <RequestPreview
            request={request}
            status={status}
            lastFilled={lastFilled}
            burstActive={burstActive}
            onShare={handleShareNow}
          />
        </div>
      </div>
    </div>
  );
}

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