/**
 * AnnotationLayer — per-page SVG overlays for text highlight annotations.
 *
 * Each page wrapper gets one <svg class="annot-layer"> absolutely positioned
 * over the canvas.  Highlight quads (in PDF coordinate space, origin
 * bottom-left) are converted to CSS pixel coordinates using the simple
 * transform:  cx = x * scale,  cy = (vpHeight - y) * scale
 * which is correct for upright (non-rotated) pages.
 *
 * Annotations from the model arrive as snake_case JSON matching the Rust
 * field names (annotation_type.type = "textmarkup", etc.).
 */
export class AnnotationLayer {
  /**
   * @param {HTMLElement[]} wrappers   - PageManager.pageWrappers (0-indexed array)
   * @param {Array<{width:number,height:number}>} viewports - scale=1 page dims
   * @param {Function} onAnnotationClick - (annotationId: string) => void
   */
  constructor(wrappers, viewports, onAnnotationClick) {
    this._wrappers          = wrappers;
    this._viewports         = viewports;
    this._onAnnotationClick = onAnnotationClick;
    this._annotations       = [];
    this._scale             = 1;
    this._selectedId        = null;
  }

  /**
   * Replace the full annotation list and re-render every page overlay.
   *
   * @param {object[]} annotations - Annotation objects from the backend
   * @param {number}   scale       - Current CSS display scale
   */
  setAnnotations(annotations, scale) {
    this._annotations = annotations || [];
    this._scale       = scale;
    for (let i = 0; i < this._wrappers.length; i++) {
      this._renderPage(i + 1);
    }
  }

  /** Called by viewer when zoom debounce fires; re-renders all overlays. */
  onScaleChange(scale) {
    this._scale = scale;
    for (let i = 0; i < this._wrappers.length; i++) {
      this._renderPage(i + 1);
    }
  }

  /**
   * Mark one annotation as visually selected (adds .selected CSS class).
   * Pass null to clear the selection.
   *
   * @param {string|null} id
   */
  selectAnnotation(id) {
    if (this._selectedId) {
      document.querySelectorAll(`.annot-layer [data-id="${CSS.escape(this._selectedId)}"]`)
        .forEach(el => el.classList.remove("selected"));
    }
    this._selectedId = id;
    if (id) {
      document.querySelectorAll(`.annot-layer [data-id="${CSS.escape(id)}"]`)
        .forEach(el => el.classList.add("selected"));
    }
  }

  // ── Private ────────────────────────────────────────────────────────────────

  _renderPage(pageNum) {
    const i    = pageNum - 1;
    const wrap = this._wrappers[i];
    if (!wrap) return;

    // Remove any existing overlay for this page
    wrap.querySelector(".annot-layer")?.remove();

    const vp0   = this._viewports[i];
    const scale = this._scale;
    const cssW  = vp0.width  * scale;
    const cssH  = vp0.height * scale;

    // Collect highlights for this page (page field is 0-indexed in the model)
    const highlights = this._annotations.filter(a =>
      a.page === i &&
      a.annotation_type?.type         === "textmarkup" &&
      a.annotation_type?.markup_type  === "highlight"
    );
    if (highlights.length === 0) return;

    const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    svg.classList.add("annot-layer");
    svg.setAttribute("viewBox", `0 0 ${cssW} ${cssH}`);
    svg.style.width  = cssW + "px";
    svg.style.height = cssH + "px";

    for (const ann of highlights) {
      for (const quad of ann.annotation_type.quads ?? []) {
        const pts = (quad.points ?? []).map(pt => {
          const cx = pt.x * scale;
          const cy = (vp0.height - pt.y) * scale;
          return `${cx},${cy}`;
        }).join(" ");

        const polygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
        polygon.setAttribute("points", pts);
        polygon.classList.add("highlight");
        polygon.dataset.id = ann.id;
        if (this._selectedId === ann.id) polygon.classList.add("selected");

        polygon.addEventListener("click", ev => {
          ev.stopPropagation();
          this._onAnnotationClick?.(ann.id);
        });

        svg.appendChild(polygon);
      }
    }

    wrap.appendChild(svg);
  }
}
