/* global React */
// EavesdropPanel.jsx — overlay that shows every LLM call's input + output.
// Subscribes to window.MM_EAVESDROP for live updates. Each entry is expandable.

const { useState: useStateE, useEffect: useEffectE } = React;

function EavesdropPanel({ onClose }) {
  const [entries, setEntries] = useStateE([]);
  const [openId, setOpenId] = useStateE(null);

  useEffectE(() => {
    return window.MM_EAVESDROP.subscribe(setEntries);
  }, []);

  const fmtTime = (iso) => {
    if (!iso) return '—';
    const d = new Date(iso);
    return d.toLocaleTimeString([], { hour12: false }) + '.' +
           String(d.getMilliseconds()).padStart(3, '0');
  };

  return (
    <div className="eav-overlay" onClick={onClose}>
      <div className="eav-panel" onClick={(e) => e.stopPropagation()}>
        <div className="eav-head">
          <div>
            <div className="eav-title">Eavesdropper</div>
            <div className="eav-sub">
              {entries.length} LLM call{entries.length === 1 ? '' : 's'} captured · most recent first
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <button className="eav-btn" onClick={() => window.MM_EAVESDROP.clear()}>Clear</button>
            <button className="eav-btn" onClick={onClose} title="Close">✕</button>
          </div>
        </div>
        <div className="eav-body">
          {entries.length === 0 && (
            <div className="eav-empty">
              No calls yet. Trigger Structure / Auto-style / Analyse / Refine / Generate and they'll show up here.
            </div>
          )}
          {entries.map((e) => (
            <EavesdropEntry key={e.id} entry={e}
                            open={openId === e.id}
                            onToggle={() => setOpenId(openId === e.id ? null : e.id)}
                            fmtTime={fmtTime} />
          ))}
        </div>
      </div>
    </div>
  );
}

function EavesdropEntry({ entry, open, onToggle, fmtTime }) {
  const dot = entry.status === 'pending' ? '#E8A65C'
            : entry.status === 'error'   ? '#E13B3B'
            :                              '#6FA8C9';

  const partsCount = (entry.parts && entry.parts.length) || 0;
  return (
    <div className={`eav-entry${open ? ' open' : ''}`}>
      <button className="eav-row" onClick={onToggle}>
        <span className="eav-dot" style={{ background: dot }} />
        <span className="eav-prompt">{entry.promptId}</span>
        <span className="eav-model">{entry.model}</span>
        <span className="eav-time">{fmtTime(entry.startedAt)}</span>
        <span className="eav-dur">
          {entry.durationMs != null ? `${entry.durationMs} ms` : '…'}
        </span>
        {partsCount > 0 && <span className="eav-tag">+{partsCount} part{partsCount === 1 ? '' : 's'}</span>}
        {entry.status === 'error' && <span className="eav-tag err">error</span>}
        <span className="eav-caret">{open ? '▾' : '▸'}</span>
      </button>
      {open && (
        <div className="eav-detail">
          {entry.error && (
            <Block label="error" content={entry.error} mono error />
          )}
          <Block label="vars (input to {{template}})"
                 content={JSON.stringify(entry.vars || {}, null, 2)} mono />
          {entry.systemText && (
            <Block label="system instruction" content={entry.systemText} />
          )}
          <Block label="user prompt (rendered, sent to model)"
                 content={entry.userText} />
          {partsCount > 0 && (
            <Block label={`extra parts (${partsCount})`}
                   content={JSON.stringify(entry.parts, null, 2)} mono />
          )}
          {entry.response && (
            <ResponseBlock response={entry.response} />
          )}
          <CopyBar entry={entry} />
        </div>
      )}
    </div>
  );
}

function Block({ label, content, mono, error }) {
  return (
    <div className="eav-block">
      <div className="eav-label">{label}</div>
      <pre className={`eav-pre${mono ? ' mono' : ''}${error ? ' err' : ''}`}>{content}</pre>
    </div>
  );
}

function ResponseBlock({ response }) {
  if (!response) return null;
  if (response.kind === 'text') {
    return <Block label="response (text)" content={response.text} />;
  }
  if (response.kind === 'json') {
    return <Block label="response (parsed JSON)" content={JSON.stringify(response.value, null, 2)} mono />;
  }
  if (response.kind === 'audio') {
    return (
      <div className="eav-block">
        <div className="eav-label">response (audio)</div>
        <pre className="eav-pre mono">{`mimeType: ${response.mimeType}
byteSize: ${response.byteSize.toLocaleString()} bytes
lyricsText: ${response.lyricsText ? JSON.stringify(response.lyricsText) : '(none)'}
url: ${response.url}`}</pre>
        {response.url && (
          <audio controls src={response.url} style={{ width: '100%', marginTop: 6 }} />
        )}
      </div>
    );
  }
  return <Block label="response" content={JSON.stringify(response, null, 2)} mono />;
}

function CopyBar({ entry }) {
  const copy = (label, text) => {
    try {
      navigator.clipboard.writeText(text);
    } catch {}
  };
  return (
    <div className="eav-copybar">
      <button className="eav-btn" onClick={() => copy('user', entry.userText)}>Copy prompt</button>
      <button className="eav-btn" onClick={() => copy('full', JSON.stringify(entry, null, 2))}>Copy entry JSON</button>
    </div>
  );
}

window.EavesdropPanel = EavesdropPanel;
