// Draggable annotation text — sits above nodes/edges. Can attach to a node
// or an edge with a curved line whose color follows the writing's text color.
function Writing({
  writing, selected, dragging, worldZoom,
  onSelect, onDrag, onDragEnd,
  onStartConnect, onDelete, onTextChange,
  onMeasure,
}){
  const moveState = React.useRef(null);
  const rootRef = React.useRef(null);
  const [editing, setEditing] = React.useState(false);

  // Report the writing's actual unrotated bbox up to Canvas so the connection
  // line can start exactly at the visible text edge — character-width estimates
  // (esp. for CJK) are unreliable enough to put the line under the text.
  React.useLayoutEffect(() => {
    if (!rootRef.current || !onMeasure) return;
    const el = rootRef.current;
    const measure = () => {
      onMeasure(writing.id, { w: el.offsetWidth, h: el.offsetHeight });
    };
    measure();
    // Re-measure once webfonts are ready — Yusei Magic loads asynchronously and
    // the first paint uses fallback metrics.
    if (document.fonts && document.fonts.ready && document.fonts.ready.then) {
      document.fonts.ready.then(measure).catch(() => {});
    }
  }, [writing.text, writing.fontSize, editing, onMeasure]);

  const onPointerDown = (e) => {
    if (e.target.closest('.connect-handle')) return;
    if (e.target.closest('.delete-btn')) return;
    if (e.target.closest('.w-edit-area')) {
      // While editing, let the textarea handle native selection but stop bubble.
      e.stopPropagation();
      return;
    }
    e.stopPropagation();
    onSelect(writing.id);
    if (editing) return;
    const startX = e.clientX, startY = e.clientY;
    const ox = writing.x, oy = writing.y;
    moveState.current = { startX, startY, ox, oy, moved: false };
    e.currentTarget.setPointerCapture(e.pointerId);
  };

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

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

  const handleConnectDown = (e) => {
    e.stopPropagation();
    e.preventDefault();
    onStartConnect(writing.id, e);
  };

  const onDoubleClick = (e) => {
    e.stopPropagation();
    setEditing(true);
  };

  const className =
    'writing'
    + (selected ? ' selected' : '')
    + (dragging ? ' dragging' : '');

  const rotation = writing.rotation || 0;
  const style = {
    left: writing.x,
    top: writing.y,
    color: writing.color || '#3a2c3a',
    fontSize: (writing.fontSize || 28) + 'px',
    transform: `translate(-50%, -50%) rotate(${rotation}deg)`,
  };

  return (
    <div
      ref={rootRef}
      className={className}
      style={style}
      onPointerDown={onPointerDown}
      onPointerMove={onPointerMove}
      onPointerUp={onPointerUp}
      onPointerCancel={onPointerUp}
      onDoubleClick={onDoubleClick}
    >
      {editing ? (
        <textarea
          className="w-edit-area"
          autoFocus
          value={writing.text || ''}
          onChange={(e)=>onTextChange(writing.id, e.target.value)}
          onBlur={()=>setEditing(false)}
          onKeyDown={(e)=>{
            if (e.key === 'Escape') { e.currentTarget.blur(); }
          }}
          rows={Math.max(1, (writing.text || '').split('\n').length)}
        />
      ) : (
        <span className="w-text">{writing.text || ' '}</span>
      )}
      <div className="connect-handle"
           onPointerDown={handleConnectDown}
           title="ドラッグでノードや矢印につなぐ">＋</div>
      <div className="delete-btn"
           onClick={(e)=>{e.stopPropagation(); onDelete(writing.id);}}
           title="削除">×</div>
    </div>
  );
}

window.Writing = Writing;
