/**
 * Shortcuts-cheatsheet popover — floating frosted-glass list of every
 * editor keyboard shortcut, anchored above the topbar keyboard icon
 * (drops below if there's no room above). Drag the header to move;
 * Esc or click outside dismisses; position is persisted in
 * localStorage so re-opening restores where the user left it.
 *
 * Public API: `toggleShortcuts(show?)` — true/false to force a state,
 * undefined to toggle.
 *
 * @returns {{ toggleShortcuts: (show?: boolean) => void }}
 */
import { shortcutsPopupHTML } from './build/popups.js';

export function createShortcutsPopover() {
  let pop = null;
  let outside = null;

  function ensurePopover() {
    if (pop) return pop;
    const el = document.createElement('div');
    el.id = 'ge-shortcuts-popover';
    el.style.cssText = [
      'position:fixed', 'z-index:10000', 'display:none',
      // Frosted-glass background: semi-transparent + heavy blur of
      // what's behind. Layered with an inner translucent veil so
      // light themes also read clearly without losing the see-through
      // feel.
      'background:color-mix(in srgb, var(--panel, #1a1a1a) 55%, transparent)',
      'backdrop-filter:blur(18px) saturate(150%)',
      '-webkit-backdrop-filter:blur(18px) saturate(150%)',
      'color:var(--fg,#eee)',
      'border:1px solid color-mix(in srgb, var(--fg, #eee) 18%, transparent)',
      'border-radius:12px',
      'box-shadow:0 14px 36px rgba(0,0,0,0.5), inset 0 1px 0 color-mix(in srgb, var(--fg, #fff) 8%, transparent)',
      'padding:12px 14px', 'min-width:540px', 'max-width:min(720px,92vw)',
      'font-size:12px', 'line-height:1.5',
    ].join(';');
    el.innerHTML = shortcutsPopupHTML();
    document.body.appendChild(el);
    el.querySelector('#ge-shortcuts-close').addEventListener('click', () => toggleShortcuts(false));

    // Drag by the header handle. Position survives across opens
    // (localStorage).
    const handle = el.querySelector('#ge-shortcuts-handle');
    if (handle) {
      let drag = null;
      handle.addEventListener('pointerdown', (e) => {
        if (e.target.closest('#ge-shortcuts-close')) return;
        const r = el.getBoundingClientRect();
        drag = { dx: e.clientX - r.left, dy: e.clientY - r.top, w: r.width, h: r.height };
        handle.setPointerCapture(e.pointerId);
        handle.style.cursor = 'grabbing';
        // Mark as user-positioned so subsequent toggles don't re-anchor.
        el.dataset.userPositioned = '1';
        e.preventDefault();
      });
      handle.addEventListener('pointermove', (e) => {
        if (!drag) return;
        let left = e.clientX - drag.dx;
        let top  = e.clientY - drag.dy;
        const m = 4;
        left = Math.max(m, Math.min(left, window.innerWidth  - drag.w - m));
        top  = Math.max(m, Math.min(top,  window.innerHeight - drag.h - m));
        el.style.left = left + 'px';
        el.style.top  = top + 'px';
      });
      const endDrag = () => {
        if (!drag) return;
        drag = null;
        handle.style.cursor = 'grab';
        try {
          localStorage.setItem('ge-shortcuts-pos', JSON.stringify({
            left: el.style.left, top: el.style.top,
          }));
        } catch {}
      };
      handle.addEventListener('pointerup', endDrag);
      handle.addEventListener('pointercancel', endDrag);
    }
    pop = el;
    return pop;
  }

  function positionPopover(el, anchor) {
    // Place ABOVE the anchor, horizontally centred but clamped to
    // viewport. Falls back to BELOW if there's no room above.
    el.style.display = 'block';   // need a layout pass for accurate size
    const ar = anchor.getBoundingClientRect();
    const pr = el.getBoundingClientRect();
    const margin = 8;
    let left = ar.left + (ar.width / 2) - (pr.width / 2);
    let top = ar.top - pr.height - margin;
    if (top < margin) top = ar.bottom + margin;
    left = Math.max(margin, Math.min(left, window.innerWidth - pr.width - margin));
    top  = Math.max(margin, Math.min(top, window.innerHeight - pr.height - margin));
    el.style.left = left + 'px';
    el.style.top  = top + 'px';
  }

  function toggleShortcuts(show) {
    const el = ensurePopover();
    const open = show === undefined ? el.style.display === 'none' : show;
    if (open) {
      // Restore the user's last-dragged position if any; otherwise
      // anchor above the button.
      let saved = null;
      try { saved = JSON.parse(localStorage.getItem('ge-shortcuts-pos') || 'null'); } catch {}
      if (saved && saved.left && saved.top) {
        el.style.display = 'block';
        el.style.left = saved.left;
        el.style.top  = saved.top;
        // Re-clamp in case the viewport changed since the user dragged.
        requestAnimationFrame(() => {
          const r = el.getBoundingClientRect();
          const m = 4;
          if (r.right > window.innerWidth)  el.style.left = (window.innerWidth - r.width - m) + 'px';
          if (r.bottom > window.innerHeight) el.style.top = (window.innerHeight - r.height - m) + 'px';
          if (r.left < 0) el.style.left = m + 'px';
          if (r.top  < 0) el.style.top  = m + 'px';
        });
      } else {
        const anchor = document.getElementById('ge-shortcuts-btn');
        if (anchor) positionPopover(el, anchor);
        else el.style.display = 'block';
      }
      // Defer outside-click so the click that opened us doesn't close us.
      outside = (e) => {
        if (el.contains(e.target)) return;
        if (e.target.closest('#ge-shortcuts-btn')) return;
        toggleShortcuts(false);
      };
      setTimeout(() => document.addEventListener('mousedown', outside, true), 0);
    } else {
      el.style.display = 'none';
      if (outside) {
        document.removeEventListener('mousedown', outside, true);
        outside = null;
      }
    }
  }

  /** True when the popover is currently visible. */
  function isOpen() {
    return !!(pop && pop.style.display && pop.style.display !== 'none');
  }

  return { toggleShortcuts, isOpen };
}
