// Note (memo) — a sticky-style annotation that can either float free OR be
// anchored to a specific node / edge. Anchored notes draw a dotted line back
// to their target so the relationship is visible.
//
// Shape:
//   { id, x, y, text, color,
//     anchor: { type:'node'|'edge', id:'...' } | null }
//
// The connector line is drawn by Canvas (since it has both note and anchor in
// scope); this component only renders the card itself + the delete button.
function Note({ note, selected, onSelect, onDrag, onDragEnd, onDelete, worldZoom }){
  const moveState = React.useRef(null);

  const onPointerDown = (e) => {
    if (e.target.closest('.note-delete')) return;
    e.stopPropagation();
    onSelect(note.id);
    moveState.current = { sx:e.clientX, sy:e.clientY, ox:note.x, oy:note.y, moved:false };
    e.currentTarget.setPointerCapture(e.pointerId);
  };

  const onPointerMove = (e) => {
    if (!moveState.current) return;
    const dx = (e.clientX - moveState.current.sx) / (worldZoom || 1);
    const dy = (e.clientY - moveState.current.sy) / (worldZoom || 1);
    if (Math.abs(dx) + Math.abs(dy) > 2) moveState.current.moved = true;
    onDrag(note.id, moveState.current.ox + dx, moveState.current.oy + dy);
  };

  const onPointerUp = (e) => {
    if (!moveState.current) return;
    const moved = moveState.current.moved;
    moveState.current = null;
    onDragEnd(note.id, moved);
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch(_){}
  };

  const isAnchored = !!(note.anchor && note.anchor.type && note.anchor.id);

  return (
    <div
      className={`note${selected?' selected':''}${isAnchored?' anchored':''}`}
      style={{
        left: note.x, top: note.y,
        position:'absolute',
      }}
      onPointerDown={onPointerDown}
      onPointerMove={onPointerMove}
      onPointerUp={onPointerUp}
      onPointerCancel={onPointerUp}
    >
      <div className="note-card"
           style={note.color ? {background:note.color, borderColor:'#FDE68A'} : null}>
        {note.text || 'Note…'}
      </div>
      {/* Use Lucide SVG icon (not the "×" glyph) so the mark sits exactly at
          the geometric center of the round button — matches Node delete-btn. */}
      <div className="note-delete" onClick={(e)=>{e.stopPropagation(); onDelete(note.id);}} title="Delete">
        {window.TourIcon ? <window.TourIcon name="x" size={12} stroke="currentColor" strokeWidth={3}/> : '×'}
      </div>
    </div>
  );
}

// Resolve the world-coords anchor point of a note's link target.
// Returns null if the anchor target no longer exists (e.g. the linked
// node/edge was deleted) — the caller treats as "not anchored".
//
// For an edge-anchored note we point at the BOTTOM of the label pill (the
// pill is 26px tall, so anchor y = labelY + 14) — that way the dotted line
// reads as "this memo annotates this label" rather than crossing through it.
// `edgeOffset` is the same offset Canvas computes for parallel edges; pass
// the matching one so curved edges get an accurate label position.
function resolveNoteAnchor(note, nodes, edges, edgeOffsets){
  const a = note?.anchor;
  if (!a || !a.type || !a.id) return null;
  if (a.type === 'node'){
    const n = nodes.find(x => x.id === a.id);
    return n ? { x: n.x, y: n.y } : null;
  }
  if (a.type === 'edge'){
    const e = edges.find(x => x.id === a.id);
    if (!e) return null;
    if (window.computeEdgeLabelPosition){
      const idx = edges.indexOf(e);
      const off = edgeOffsets ? (edgeOffsets[idx] || 0) : 0;
      const nodesById = Object.fromEntries(nodes.map(n => [n.id, n]));
      // labelOffsetY = +14 → anchor sits on the pill's bottom edge so the
      // dotted line approaches the label from below.
      return window.computeEdgeLabelPosition(e, nodesById, off, 14);
    }
    // Fallback if the helper isn't loaded yet.
    const from = nodes.find(n => n.id === e.from);
    const to   = nodes.find(n => n.id === e.to);
    if (!from || !to) return null;
    return { x: (from.x + to.x)/2, y: (from.y + to.y)/2 };
  }
  return null;
}

window.Note = Note;
window.resolveNoteAnchor = resolveNoteAnchor;
