// Show in preview: outlines the failing element with its issue number. The server loads this script only for a
// logged-in user who may edit the post, with a valid nonce, so visitors never get it. Everything is drawn in one
// overlay element with its own shadow root, so the page's elements and styles stay untouched.
import { resolveSelector } from "./check/dom";
import { waysillData } from "./data";

const STYLE = `
:host { all: initial; }
.layer { position: fixed; inset: 0; pointer-events: none; z-index: 2147483646; }
.box { position: fixed; box-sizing: border-box; border: 3px solid #b3001b; outline: 2px solid #ffffff; border-radius: 2px; }
.badge { position: fixed; min-width: 24px; height: 24px; padding: 0 6px; box-sizing: border-box; border-radius: 12px;
  background: #b3001b; color: #ffffff; border: 2px solid #ffffff; font: 700 13px/20px system-ui, sans-serif; text-align: center; }
.message { position: fixed; left: 16px; bottom: 16px; max-width: 420px; padding: 10px 14px; border-radius: 4px;
  background: #1d2327; color: #ffffff; font: 14px/1.4 system-ui, sans-serif; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
`;

function show(): void {
  const target = waysillData().highlight;
  if (!target) return;
  const host = document.createElement("div");
  host.setAttribute("data-waysill-highlight", String(target.number));
  const shadow = host.attachShadow({ mode: "open" });
  const style = document.createElement("style");
  style.textContent = STYLE;
  const layer = document.createElement("div");
  layer.className = "layer";
  const status = document.createElement("div");
  status.setAttribute("role", "status");
  shadow.append(style, layer, status);
  document.body.append(host);

  const element = resolveSelector(target.selector);
  if (!element) {
    status.className = "message";
    status.textContent = `Waysill: issue ${target.number} (${target.title}) was not found on this page. The content may have changed since the last check.`;
    return;
  }
  status.className = "sr";
  status.textContent = `Waysill: issue ${target.number} is outlined: ${target.title}`;
  const box = document.createElement("div");
  box.className = "box";
  const badge = document.createElement("div");
  badge.className = "badge";
  badge.textContent = String(target.number);
  layer.append(box, badge);

  // Viewport coordinates, so the outline follows scrolling and resizing; one redraw per animation frame.
  let frame = 0;
  const draw = () => {
    frame = 0;
    const r = element.getBoundingClientRect();
    Object.assign(box.style, { left: `${r.left - 3}px`, top: `${r.top - 3}px`, width: `${r.width + 6}px`, height: `${r.height + 6}px` });
    Object.assign(badge.style, { left: `${Math.max(0, r.left - 14)}px`, top: `${Math.max(0, r.top - 14)}px` });
  };
  const update = () => {
    if (!frame) frame = requestAnimationFrame(draw);
  };
  element.scrollIntoView({ block: "center", inline: "nearest" });
  draw();
  window.addEventListener("scroll", update, { capture: true, passive: true });
  window.addEventListener("resize", update, { passive: true });
}

if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", show, { once: true });
else show();
