// Общее контекстное меню узла (долгое нажатие) для карты связей.
// Рендерится в #modal-root (вне масштабируемого холста), позиционируется по экранному rect узла.
// Используется и реальным путём (network-view.js), и лабораторией (lab.js).

const REL_RU = {
  family: 'Семья',
  friend: 'Друг',
  business: 'Бизнес',
  contact: 'Контакт',
  self: 'Вы',
};

function escapeHtml(text) {
  return String(text || '')
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}

export function relationLabelRu(relationType) {
  return REL_RU[relationType] || 'Контакт';
}

/**
 * Открывает контекстное меню узла.
 * @param {Object} opts
 * @param {string} opts.login - логин/идентификатор для заголовка
 * @param {string} opts.relationType - тип связи (для подписи)
 * @param {{x:number,y:number,rect?:DOMRect}} opts.point - экранная точка/rect узла
 * @param {Array<{label:string, onClick:Function, disabled?:boolean}>} opts.actions - пункты меню
 */
export function openNodeMenu({ login, relationType, point, actions = [] } = {}) {
  const root = document.getElementById('modal-root');
  if (!(root instanceof HTMLElement)) return;

  const itemsHtml = actions
    .map((a, i) => `<button class="fg-menu-item${a.disabled ? ' is-stub' : ''}" type="button" data-i="${i}" role="menuitem"${a.disabled ? ' disabled' : ''}>${escapeHtml(a.label)}</button>`)
    .join('');

  root.innerHTML = `
    <div class="fg-menu-overlay" id="fg-menu-overlay">
      <div class="fg-menu" id="fg-menu" role="menu">
        <div class="fg-menu-head">
          <span class="fg-menu-login">${escapeHtml(login)}</span>
          <span class="fg-menu-rel">${escapeHtml(relationLabelRu(relationType))}</span>
        </div>
        ${itemsHtml}
      </div>
    </div>
  `;

  const overlay = root.querySelector('#fg-menu-overlay');
  const menu = root.querySelector('#fg-menu');
  if (!(overlay instanceof HTMLElement) || !(menu instanceof HTMLElement)) { root.innerHTML = ''; return; }

  // позиционируем рядом с узлом по его экранному rect (синхронно, без rAF — он может троттлиться)
  const rect = point?.rect;
  const px = point?.x ?? (rect ? rect.left + rect.width / 2 : window.innerWidth / 2);
  const belowY = rect ? rect.bottom + 8 : (point?.y ?? 80);
  const mw = menu.offsetWidth;
  const mh = menu.offsetHeight;
  let left = px - mw / 2;
  left = Math.max(8, Math.min(left, window.innerWidth - mw - 8));
  let top = belowY;
  if (top + mh > window.innerHeight - 8) top = Math.max(8, (rect ? rect.top : belowY) - mh - 8);
  menu.style.left = `${left}px`;
  menu.style.top = `${top}px`;

  const close = () => { root.innerHTML = ''; };
  overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
  menu.addEventListener('click', (e) => {
    const btn = e.target instanceof HTMLElement ? e.target.closest('[data-i]') : null;
    if (!(btn instanceof HTMLElement)) return;
    const idx = Number(btn.dataset.i);
    const action = actions[idx];
    if (!action || action.disabled) return;
    close();
    if (typeof action.onClick === 'function') action.onClick();
  });

  return close;
}
