import React from 'react';
import { MODES, modeById } from '../lib/modes.js';

// NoteBody — shared note-body state renderer (loading / streaming / error / done).
// Extracted so FigurePopover can reuse the exact same state logic without copy-paste.
// Props match the shape MarginNote already uses internally.
//   entry     — commentary entry or undefined
//   generating — boolean
//   onRegenerate — () => void
export function NoteBody({ entry, generating, onRegenerate }) {
  if (generating && !entry?.text) {
    return <div className="ap-note-loading">consulting the literature<span className="ap-ellipsis"></span></div>;
  }
  if (entry && entry.streaming && entry.text) {
    return <div className="ap-note-text">{entry.text}</div>;
  }
  if (entry && entry.error) {
    return (
      <div className="ap-note-error">
        {entry.message ? entry.message + ' — ' : 'the annotator did not answer. '}
        <button className="ap-textbtn" onClick={onRegenerate}>try again</button>
      </div>
    );
  }
  if (entry) {
    return <div className="ap-note-text">{entry.text}</div>;
  }
  return <div className="ap-note-loading">awaiting annotation&hellip;</div>;
}

// MarginNote — a single margin annotation card.
// Differences from prototype:
//   1. lit lookup comes through props (litByPara, litPapers) instead of window.ASTROPARSE_DATA.
//   2. modeById imported from lib/modes.js instead of global.
//   Everything else (classNames, DOM structure, hover/mode/regen handlers) is identical.
export default function MarginNote({ para, mode, entry, generating, hovered, onHover, onSetMode, onRegenerate, onCite, top, noteRef, litByPara, litPapers, litCount, userNote, onSaveNote }) {
  const m = modeById[mode];
  const lit = (litByPara[para.id] || []).slice(0, litCount ?? 3).map((id) => litPapers[id]).filter(Boolean);

  const [noteOpen, setNoteOpen] = React.useState(false);
  const [draftText, setDraftText] = React.useState(userNote?.text || '');
  const timerRef = React.useRef(null);

  React.useEffect(() => { setDraftText(userNote?.text || ''); }, [userNote?.text]);
  React.useEffect(() => { return () => { if (timerRef.current) clearTimeout(timerRef.current); }; }, []);

  const handleNoteChange = (e) => {
    const val = e.target.value;
    setDraftText(val);
    if (timerRef.current) clearTimeout(timerRef.current);
    timerRef.current = setTimeout(() => {
      onSaveNote && onSaveNote(para.id, val);
    }, 400);
  };

  const handleNoteBlur = () => {
    if (timerRef.current) clearTimeout(timerRef.current);
    onSaveNote && onSaveNote(para.id, draftText);
    if (!draftText.trim()) setNoteOpen(false);
  };

  return (
    <aside
      ref={noteRef}
      className={'ap-note' + (hovered ? ' is-hovered' : '')}
      style={{ top: top, '--mode-c': 'var(--mc-' + mode + ')' }}
      onMouseEnter={() => onHover(para.id)}
      onMouseLeave={() => onHover(null)}
      data-comment-anchor={'note-' + para.id}
    >
      <div className="ap-note-head">
        <span className="ap-note-mode">{m.label}</span>
        {entry && entry.source === 'llm' && !generating && <span className="ap-note-gen" title="generated by the annotator">&#10022;</span>}
        {entry && !generating && (
          <button className="ap-note-regen" title="regenerate this note" onClick={() => onRegenerate(para.id, mode)}>&#8635;</button>
        )}
        <button
          className={'ap-note-write' + (noteOpen || userNote?.text ? ' is-active' : '')}
          title="write a note"
          onClick={() => { setNoteOpen(true); }}
        >&#x270E;</button>
      </div>
      <NoteBody entry={entry} generating={generating} onRegenerate={() => onRegenerate(para.id, mode)} />
      {lit.length > 0 && (
        <div className="ap-note-cites">
          {lit.map((l, i) => (
            <button key={l.id} className="ap-cite" onClick={(e) => onCite(l, e)}>
              <span className="ap-cite-n">{i + 1}</span> {l.short}
            </button>
          ))}
        </div>
      )}
      <div className="ap-note-modes" role="group" aria-label="commentary mode">
        {MODES.map((mm) => (
          <button
            key={mm.id}
            className={'ap-mode-dot' + (mm.id === mode ? ' is-active' : '')}
            style={{ '--mode-c': 'var(--mc-' + mm.id + ')' }}
            title={mm.label}
            onClick={() => onSetMode(para.id, mm.id)}
          >{mm.glyph}</button>
        ))}
      </div>
      {(noteOpen || userNote?.text) && (
        <div className="ap-user-note">
          <span className="ap-user-note-mark">&#x270E;</span>
          <textarea
            className="ap-user-note-text"
            value={draftText}
            placeholder="your notes…"
            onChange={handleNoteChange}
            onBlur={handleNoteBlur}
            autoFocus={noteOpen && !userNote?.text}
            rows={1}
            onInput={(e) => {
              e.target.style.height = 'auto';
              e.target.style.height = e.target.scrollHeight + 'px';
            }}
          />
        </div>
      )}
    </aside>
  );
}
