(() => {
  if (globalThis.MMWSourceTracePopover) return;

  const ROOT_CLASS = "mmw-source-results-popover";
  const STYLE_ID = "mmw-source-results-popover-style";
  let active = null;

  function close() {
    if (!active) return;
    window.removeEventListener("resize", active.reposition, true);
    window.removeEventListener("scroll", active.reposition, true);
    document.removeEventListener("keydown", active.onKeydown, true);
    active.root.remove();
    active = null;
  }

  function open({ anchor, getAnchor, items, onDownload }) {
    let currentAnchor = resolveAnchor(anchor, getAnchor);
    if (!currentAnchor || !Array.isArray(items) || !items.length) return false;
    close();
    ensureStyle();

    const root = document.createElement("section");
    root.className = ROOT_CLASS;
    root.setAttribute("role", "dialog");
    root.setAttribute("aria-label", "溯源素材");

    const header = document.createElement("header");
    const heading = document.createElement("strong");
    heading.textContent = `溯源素材（${items.length}）`;
    const closeButton = document.createElement("button");
    closeButton.type = "button";
    closeButton.className = "mmw-source-results-close";
    closeButton.textContent = "×";
    closeButton.setAttribute("aria-label", "关闭素材列表");
    closeButton.addEventListener("click", close);
    header.append(heading, closeButton);
    root.appendChild(header);

    const list = document.createElement("div");
    list.className = "mmw-source-results-list";
    items.forEach((item, index) => list.appendChild(createRow(item, index, onDownload)));
    root.appendChild(list);
    document.body.appendChild(root);

    const reposition = () => {
      currentAnchor = resolveAnchor(currentAnchor, getAnchor) || currentAnchor;
      position(root, currentAnchor);
    };
    const onKeydown = (event) => {
      if (event.key === "Escape") close();
    };
    active = { root, reposition, onKeydown };
    window.addEventListener("resize", reposition, true);
    window.addEventListener("scroll", reposition, true);
    document.addEventListener("keydown", onKeydown, true);
    reposition();
    requestAnimationFrame(reposition);
    return true;
  }

  function resolveAnchor(fallback, getAnchor) {
    if (typeof getAnchor === "function") {
      try {
        const current = getAnchor();
        if (current instanceof Element) return current;
      } catch {}
    }
    return fallback instanceof Element ? fallback : null;
  }

  function createRow(item, index, onDownload) {
    const row = document.createElement("div");
    row.className = "mmw-source-results-item";

    const name = document.createElement("strong");
    name.textContent = `素材 ${index + 1}`;

    const meta = document.createElement("div");
    meta.className = "mmw-source-results-meta";
    if (item.isOriginal) meta.appendChild(tag("原视频", "is-original"));
    meta.appendChild(tag(item.isOriginal ? "Original" : formatLabel(item)));
    meta.appendChild(tag(sizeLabel(item)));

    const downloadButton = document.createElement("button");
    downloadButton.type = "button";
    downloadButton.className = "mmw-source-results-download";
    downloadButton.textContent = "下载";
    downloadButton.addEventListener("click", async () => {
      if (downloadButton.disabled) return;
      downloadButton.disabled = true;
      downloadButton.textContent = "下载中…";
      try {
        const result = await onDownload?.(item);
        if (result?.cancelled) {
          downloadButton.disabled = false;
          downloadButton.textContent = "下载";
          return;
        }
        downloadButton.textContent = "已提交";
      } catch {
        downloadButton.disabled = false;
        downloadButton.textContent = "重试";
      }
    });

    row.append(name, meta, downloadButton);
    return row;
  }

  function tag(value, className = "") {
    const node = document.createElement("span");
    node.textContent = value;
    if (className) node.className = className;
    return node;
  }

  function formatLabel(item) {
    const resolution = String(item.resolution || "").trim();
    if (resolution) return resolution;
    const extension = String(item.extension || "mp4").replace(/^\./, "").trim();
    return extension ? extension.toUpperCase() : "MP4";
  }

  function sizeLabel(item) {
    const text = String(item.sizeText || "").trim();
    if (text) return text;
    const bytes = Number(item.size || 0);
    if (!Number.isFinite(bytes) || bytes <= 0) return "--";
    const units = ["B", "KB", "MB", "GB"];
    let value = bytes;
    let index = 0;
    while (value >= 1024 && index < units.length - 1) {
      value /= 1024;
      index += 1;
    }
    return `${index === 0 ? Math.round(value) : value.toFixed(2)} ${units[index]}`;
  }

  function position(root, anchor) {
    const gap = 10;
    const margin = 10;
    const rootRect = root.getBoundingClientRect();
    const width = rootRect.width || 330;
    const height = rootRect.height || 180;
    if (!anchor.isConnected) {
      place(root, rootRect.left, rootRect.top, width, height, margin);
      return;
    }
    const anchorRect = anchor.getBoundingClientRect();
    let left = anchorRect.right + gap;
    if (left + width > window.innerWidth - margin) left = anchorRect.left - width - gap;
    place(root, left, anchorRect.top - 8, width, height, margin);
  }

  function place(root, left, top, width, height, margin) {
    const maxLeft = Math.max(margin, window.innerWidth - width - margin);
    const maxTop = Math.max(margin, window.innerHeight - height - margin);
    root.style.left = `${Math.round(Math.max(margin, Math.min(left, maxLeft)))}px`;
    root.style.top = `${Math.round(Math.max(margin, Math.min(top, maxTop)))}px`;
  }

  function ensureStyle() {
    if (document.getElementById(STYLE_ID)) return;
    const style = document.createElement("style");
    style.id = STYLE_ID;
    style.textContent = `
      .${ROOT_CLASS} {
        position: fixed;
        z-index: 2147483646;
        width: min(330px, calc(100vw - 20px));
        max-height: min(420px, calc(100vh - 20px));
        overflow: hidden;
        color: #172033;
        background: #fff;
        border: 1px solid #dfe5ef;
        border-radius: 12px;
        box-shadow: 0 16px 40px rgba(18, 29, 51, .2);
        font: 13px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif;
      }
      .${ROOT_CLASS} header {
        height: 44px;
        padding: 0 10px 0 14px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-bottom: 1px solid #edf0f5;
      }
      .${ROOT_CLASS} header strong {
        font-size: 14px;
        font-weight: 700;
      }
      .mmw-source-results-close {
        width: 30px;
        height: 30px;
        border: 0;
        border-radius: 8px;
        color: #536176;
        background: transparent;
        font-size: 22px;
        line-height: 1;
        cursor: pointer;
      }
      .mmw-source-results-close:hover {
        background: #f1f4f8;
      }
      .mmw-source-results-list {
        max-height: min(374px, calc(100vh - 66px));
        overflow: auto;
        overscroll-behavior: contain;
      }
      .mmw-source-results-item {
        min-height: 56px;
        padding: 10px 12px 10px 14px;
        display: grid;
        grid-template-columns: 58px minmax(0, 1fr) auto;
        gap: 8px;
        align-items: center;
        border-bottom: 1px solid #edf0f5;
      }
      .mmw-source-results-item:last-child {
        border-bottom: 0;
      }
      .mmw-source-results-item > strong {
        font-size: 13px;
        white-space: nowrap;
      }
      .mmw-source-results-meta {
        min-width: 0;
        display: flex;
        gap: 5px;
        align-items: center;
        flex-wrap: wrap;
      }
      .mmw-source-results-meta span {
        padding: 2px 6px;
        border-radius: 999px;
        color: #59677c;
        background: #eef2f7;
        font-size: 11px;
        white-space: nowrap;
      }
      .mmw-source-results-meta .is-original {
        color: #138a55;
        background: #e7f8ef;
      }
      .mmw-source-results-download {
        min-width: 52px;
        height: 30px;
        padding: 0 10px;
        border: 0;
        border-radius: 8px;
        color: #fff;
        background: #2468e5;
        font-weight: 600;
        cursor: pointer;
      }
      .mmw-source-results-download:hover {
        background: #1758cc;
      }
      .mmw-source-results-download:disabled {
        cursor: wait;
        opacity: .68;
      }
      .mmw-source-results-close:focus-visible,
      .mmw-source-results-download:focus-visible {
        outline: 2px solid #2468e5;
        outline-offset: 2px;
      }
      @media (max-width: 520px) {
        .${ROOT_CLASS} {
          width: calc(100vw - 20px);
        }
      }
    `;
    document.head.appendChild(style);
  }

  globalThis.MMWSourceTracePopover = Object.freeze({ open, close });
})();
