/**
 * MessageBridge — postMessage protocol between the PDF viewer iframe
 * and the parent Leptos application.
 *
 * Inbound  (parent → iframe):
 *   "pdf.page.next" | "pdf.page.prev"
 *   { type: "brittle:annotations-set", annotations: [...] }
 *
 * Outbound (iframe → parent):
 *   { type: "brittle:keydown",              key, ctrlKey, … }
 *   { type: "brittle:viewer-state",         refId, zoom, scrollTop }
 *   { type: "brittle:annotations-request",  refId }
 *   { type: "brittle:annotation-create",    refId, page, quads, selectedText }
 *   { type: "brittle:annotation-click",     refId, annotationId }
 */
export class MessageBridge {
  /**
   * @param {Function} onPageNext      - () => void
   * @param {Function} onPagePrev      - () => void
   * @param {object}   [options]
   * @param {Function} [options.onAnnotationsSet] - (annotations: object[]) => void
   */
  constructor(onPageNext, onPagePrev, options = {}) {
    this._onAnnotationsSet = options.onAnnotationsSet ?? null;

    this._handler = ev => {
      if (ev.data === "pdf.page.next") { onPageNext(); return; }
      if (ev.data === "pdf.page.prev") { onPagePrev(); return; }
      if (ev.data?.type === "brittle:annotations-set") {
        this._onAnnotationsSet?.(ev.data.annotations ?? []);
      }
    };
    window.addEventListener("message", this._handler);
  }

  // ── Outbound ───────────────────────────────────────────────────────────────

  /** Send the current viewer state (zoom + scroll) to the parent window. */
  postViewerState(refId, zoom, scrollTop) {
    if (window.parent === window) return;
    window.parent.postMessage({
      type: "brittle:viewer-state",
      refId,
      zoom,
      scrollTop,
    }, "*");
  }

  /** Ask the parent to send the annotation set for this reference. */
  requestAnnotations(refId) {
    if (window.parent === window) return;
    window.parent.postMessage({ type: "brittle:annotations-request", refId }, "*");
  }

  /**
   * Notify the parent that the user selected text and wants to create a
   * highlight annotation.
   *
   * @param {string}   refId
   * @param {number}   page         - 0-indexed physical page number
   * @param {object[]} quads        - [{points:[{x,y}×4]}] in PDF coordinate space
   * @param {string}   selectedText
   */
  postAnnotationCreate(refId, page, quads, selectedText) {
    if (window.parent === window) return;
    window.parent.postMessage({
      type: "brittle:annotation-create",
      refId,
      page,
      quads,
      selectedText,
    }, "*");
  }

  /**
   * Notify the parent that the user clicked an existing annotation.
   *
   * @param {string} refId
   * @param {string} annotationId
   */
  postAnnotationClick(refId, annotationId) {
    if (window.parent === window) return;
    window.parent.postMessage({
      type: "brittle:annotation-click",
      refId,
      annotationId,
    }, "*");
  }

  /** Forward a keydown event to the parent window for global keybindings. */
  forwardKeydown(ev) {
    if (window.parent === window) return;
    window.parent.postMessage({
      type:     "brittle:keydown",
      key:      ev.key,
      ctrlKey:  ev.ctrlKey,
      shiftKey: ev.shiftKey,
      altKey:   ev.altKey,
      metaKey:  ev.metaKey,
    }, "*");
  }

  disconnect() {
    window.removeEventListener("message", this._handler);
  }
}
