(() => {
  if (window.__MRP_SCANNER__) {
    window.__MRP_SCANNER__.scan();
    return;
  }

  const AUTH_KEY = "pluginAuth";
  const IMAGE_EXTENSIONS = /\.(apng|avif|bmp|gif|jpe?g|png|svg|webp)(\?|#|$)/i;
  const MEDIA_EXTENSIONS = /\.(3g2|3gp|aac|avi|flac|m3u8|m4a|m4s|m4v|mkv|mov|mp3|mp4|mpeg|mpd|oga|ogg|ogv|ts|wav|webm)(\?|#|$)/i;
  const BLOCKED_SCHEMES = /^(data|blob|chrome|chrome-extension|edge):/i;
  const CARD_META_TTL_MS = 8000;
  const CARD_META_SEND_INTERVAL_MS = 450;
  const DOUYIN_CARD_SELECTOR = [
    '[data-e2e="feed-active-video"]',
    '[data-e2e="feed-item"]',
    '[data-e2e="feed-video"]',
    '[id^="waterfall_item_"]',
    ".search-result-card"
  ].join(",");
  const DOUYIN_PROFILE_LINK_SELECTOR = 'a[href*="/video/"], a[href*="/note/"]';
  const state = {
    authActive: true,
    activeCardMeta: null,
    lastCardMetaKey: "",
    lastCardMetaSentAt: 0
  };

  window.__MRP_SCANNER__ = { scan, refreshAuthState };
  refreshAuthState();
  chrome.storage.onChanged.addListener((changes, area) => {
    if (area !== "local" || !changes[AUTH_KEY]) return;
    state.authActive = true;
    scan();
  });
  document.addEventListener("pointerover", handlePointerMove, true);
  document.addEventListener("pointermove", handlePointerMove, true);

  function scan() {
    const resources = [];
    const seen = new Set();

    for (const image of document.images) {
      push(resources, seen, image.currentSrc || image.src, "dom-image", image.type || "image", readImageMeta(image, image.currentSrc || image.src));
      for (const src of parseSrcset(image.srcset)) {
        push(resources, seen, src, "dom-image-srcset", "image", readImageMeta(image, src));
      }
    }

    for (const media of document.querySelectorAll("video,audio")) {
      const kind = media.tagName.toLowerCase() === "audio" ? "audio" : "video";
      push(resources, seen, media.currentSrc || media.src, `dom-${kind}`, kind, kind === "video" ? readVideoMeta(media) : null);
      if (media.poster) {
        push(resources, seen, media.poster, "dom-video-poster", "image", readImageMeta(media, media.poster));
      }
    }

    for (const source of document.querySelectorAll("source,track")) {
      push(resources, seen, source.src, "dom-source", source.type || "");
      for (const src of parseSrcset(source.srcset)) {
        push(resources, seen, src, "dom-source-srcset", source.type || "");
      }
    }

    for (const link of document.querySelectorAll("a[href]")) {
      const href = link.href;
      if (IMAGE_EXTENSIONS.test(href)) {
        push(resources, seen, href, "dom-link", "image", readUrlMeta(href));
      } else if (MEDIA_EXTENSIONS.test(href)) {
        push(resources, seen, href, "dom-link", "media");
      }
    }

    for (const element of document.querySelectorAll("body, body *")) {
      const value = getComputedStyle(element).backgroundImage;
      if (!value || value === "none") {
        continue;
      }
      for (const url of parseCssUrls(value)) {
        push(resources, seen, url, "dom-background", "image", readBackgroundImageMeta(element, url));
      }
    }

    if (resources.length) {
      chrome.runtime.sendMessage({ type: "CONTENT_RESOURCES", resources }).catch(() => {});
    }

    const primaryMeta = readPrimaryVideoMeta();
    if (primaryMeta.cardId || primaryMeta.authorName || primaryMeta.likeCountText || primaryMeta.videoTitle) {
      state.activeCardMeta = { ...primaryMeta, time: Date.now() };
      sendCardMeta(state.activeCardMeta);
    }
  }

  async function refreshAuthState() {
    state.authActive = true;
    scan();
  }

  function isAuthActive(value) {
    return Boolean(value && typeof value === "object" && value.loggedIn && value.active);
  }

  function push(resources, seen, rawUrl, source, kind, extra = null) {
    const url = absolutize(rawUrl);
    if (!url || seen.has(url) || BLOCKED_SCHEMES.test(url)) {
      return;
    }
    seen.add(url);
    resources.push({
      url,
      source,
      kind,
      mimeType: typeof kind === "string" && kind.includes("/") ? kind : "",
      ...(extra && typeof extra === "object" ? extra : {})
    });
  }

  function readVideoMeta(media) {
    const shell = resolveVideoShell(media) || resolveCardByGeometry(media);
    const cardMeta = readCardMeta(shell);
    const detailMeta = readDetailMeta(shell);
    const resourceKey = readMediaResourceKey(media) || readShellResourceKey(shell);
    if (cardMeta.cardId || cardMeta.authorName || cardMeta.likeCountText || cardMeta.sourceTraceUrl || cardMeta.videoTitle) {
      return {
        cardId: cardMeta.cardId || detailMeta.cardId || "",
        authorName: cardMeta.authorName || detailMeta.authorName || "",
        likeCountText: cardMeta.likeCountText || detailMeta.likeCountText || "",
        videoTitle: cardMeta.videoTitle || detailMeta.videoTitle || "",
        awemeId: cardMeta.awemeId || detailMeta.awemeId || "",
        sourceTraceUrl: cardMeta.sourceTraceUrl || detailMeta.sourceTraceUrl || "",
        resourceKey
      };
    }
    if ((detailMeta.authorName || detailMeta.likeCountText || detailMeta.cardId || detailMeta.sourceTraceUrl || detailMeta.videoTitle) && isDetailPage()) {
      return { ...detailMeta, resourceKey };
    }
    if (isFreshActiveCardMeta()) {
      return {
        cardId: state.activeCardMeta.cardId || "",
        authorName: state.activeCardMeta.authorName || "",
        likeCountText: state.activeCardMeta.likeCountText || "",
        videoTitle: state.activeCardMeta.videoTitle || "",
        awemeId: state.activeCardMeta.awemeId || "",
        sourceTraceUrl: state.activeCardMeta.sourceTraceUrl || "",
        resourceKey: state.activeCardMeta.resourceKey || resourceKey
      };
    }
    return {};
  }

  function readImageMeta(element, rawUrl) {
    const url = absolutize(rawUrl);
    const fileName = extractFileName(url);
    const extension = getExtension(url);
    const naturalWidth = normalizeDimension(element?.naturalWidth || element?.videoWidth || 0);
    const naturalHeight = normalizeDimension(element?.naturalHeight || element?.videoHeight || 0);
    const displayWidth = normalizeDimension(element?.clientWidth || element?.width || 0);
    const displayHeight = normalizeDimension(element?.clientHeight || element?.height || 0);
    return {
      fileName,
      extension,
      width: naturalWidth || displayWidth || 0,
      height: naturalHeight || displayHeight || 0
    };
  }

  function readBackgroundImageMeta(element, rawUrl) {
    const url = absolutize(rawUrl);
    return {
      fileName: extractFileName(url),
      extension: getExtension(url),
      width: normalizeDimension(element?.clientWidth || 0),
      height: normalizeDimension(element?.clientHeight || 0)
    };
  }

  function readUrlMeta(rawUrl) {
    const url = absolutize(rawUrl);
    return {
      fileName: extractFileName(url),
      extension: getExtension(url)
    };
  }

  function handlePointerMove(event) {
    if (!isDouyinPage()) return;
    const shell = resolveCardFromPoint(event.clientX, event.clientY);
    const meta = readCardMeta(shell);
    const resourceKey = readShellResourceKey(shell);
    if (resourceKey) meta.resourceKey = resourceKey;
    if (!meta.authorName && !meta.likeCountText && !meta.sourceTraceUrl && !meta.videoTitle) return;
    state.activeCardMeta = { ...meta, time: Date.now() };
    sendCardMeta(state.activeCardMeta);
  }

  function sendCardMeta(meta) {
    const now = Date.now();
    const key = `${meta.cardId || ""}|${meta.authorName || ""}|${meta.likeCountText || ""}|${meta.videoTitle || ""}|${meta.resourceKey || ""}|${meta.awemeId || ""}|${meta.sourceTraceUrl || ""}`;
    if (key === state.lastCardMetaKey && now - state.lastCardMetaSentAt < CARD_META_SEND_INTERVAL_MS) return;
    state.lastCardMetaKey = key;
    state.lastCardMetaSentAt = now;
    chrome.runtime.sendMessage({ type: "CONTENT_CARD_META", meta }).catch(() => {});
  }

  function isFreshActiveCardMeta() {
    return Boolean(state.activeCardMeta && Date.now() - state.activeCardMeta.time <= CARD_META_TTL_MS);
  }

  function isDouyinPage() {
    return /(^|\.)douyin\.com$/i.test(location.hostname) || /(^|\.)iesdouyin\.com$/i.test(location.hostname);
  }

  function readCardMeta(shell) {
    if (!shell || !shell.innerText) return {};
    const traceMeta = readSourceTraceMeta(shell);
    const lines = String(shell.innerText || "")
      .split(/\n+/)
      .map((line) => line.trim())
      .filter(Boolean)
      .slice(0, 20);
    return {
      cardId: buildContainerKey(shell),
      authorName: findCardAuthor(lines),
      likeCountText: findCardLike(lines),
      videoTitle: findCardTitle(lines),
      awemeId: traceMeta.awemeId,
      sourceTraceUrl: traceMeta.url
    };
  }

  function isDetailPage() {
    return /^\/(video|note)(\/|$)/i.test(location.pathname);
  }

  function readDetailMeta(scope) {
    const root = scope instanceof Element ? scope.parentElement || document : document;
    const traceMeta = readSourceTraceMeta(root);
    const authorNode = root.querySelector?.(
      '[data-e2e="feed-video-nickname"], [data-e2e="video-author-nickname"], [data-e2e="video-author-name"], [data-e2e="user-name"]'
    ) || document.querySelector(
      '[data-e2e="feed-video-nickname"], [data-e2e="video-author-nickname"], [data-e2e="video-author-name"], [data-e2e="user-name"]'
    );
    const likeNode = root.querySelector?.(
      '[data-e2e="video-player-digg"], [data-e2e="like-count"], [data-e2e="video-like-count"]'
    ) || document.querySelector(
      '[data-e2e="video-player-digg"], [data-e2e="like-count"], [data-e2e="video-like-count"]'
    );
    const titleNode = root.querySelector?.(
      '[data-e2e="video-desc"], [data-e2e="feed-video-desc"], [data-e2e="video-title"], [data-e2e="feed-video-title"]'
    ) || document.querySelector(
      '[data-e2e="video-desc"], [data-e2e="feed-video-desc"], [data-e2e="video-title"], [data-e2e="feed-video-title"]'
    );
    return {
      cardId: buildContainerKey(scope),
      authorName: normalizeAuthorText(authorNode?.textContent || ""),
      likeCountText: normalizeLikeText(likeNode?.textContent || ""),
      videoTitle: normalizeVideoTitle(titleNode?.innerText || titleNode?.textContent || ""),
      awemeId: traceMeta.awemeId,
      sourceTraceUrl: traceMeta.url
    };
  }

  function resolveVideoShell(media) {
    return resolveDouyinCardShell(media);
  }

  function resolveCardFromPoint(x, y) {
    const hit = document.elementFromPoint(
      Math.max(0, Math.min(window.innerWidth - 1, x)),
      Math.max(0, Math.min(window.innerHeight - 1, y))
    );
    const direct = resolveDouyinCardShell(hit);
    if (direct) return direct;
    return listDouyinCardShells()
      .find((shell) => {
        const rect = shell.getBoundingClientRect();
        return rect.width > 120
          && rect.height > 120
          && x >= rect.left
          && x <= rect.right
          && y >= rect.top
          && y <= rect.bottom;
      }) || null;
  }

  function resolveCardByGeometry(media) {
    if (!(media instanceof Element)) return null;
    const rect = media.getBoundingClientRect();
    if (!rect.width || !rect.height) return null;
    const candidates = listDouyinCardShells()
      .map((shell) => ({ shell, score: geometryScore(rect, shell.getBoundingClientRect()) }))
      .filter((item) => item.score > 0)
      .sort((left, right) => right.score - left.score);
    return candidates[0]?.shell || null;
  }

  function resolveDouyinCardShell(node) {
    if (!(node instanceof Element)) return null;
    const direct = node.closest(DOUYIN_CARD_SELECTOR);
    if (direct) return direct.closest?.('[id^="waterfall_item_"]') || direct;
    const listItem = node.closest("li");
    const profileLink = node.closest(DOUYIN_PROFILE_LINK_SELECTOR)
      || listItem?.querySelector?.(DOUYIN_PROFILE_LINK_SELECTOR);
    return profileLink?.closest?.("li") || profileLink || null;
  }

  function listDouyinCardShells() {
    const shells = Array.from(document.querySelectorAll(DOUYIN_CARD_SELECTOR))
      .map((shell) => shell.closest?.('[id^="waterfall_item_"]') || shell);
    for (const link of document.querySelectorAll(DOUYIN_PROFILE_LINK_SELECTOR)) {
      shells.push(link.closest("li") || link);
    }
    return shells.filter((shell, index) => shell && shells.indexOf(shell) === index);
  }

  function geometryScore(videoRect, cardRect) {
    if (cardRect.width <= 120 || cardRect.height <= 120) return 0;
    const overlapX = Math.max(0, Math.min(videoRect.right, cardRect.right) - Math.max(videoRect.left, cardRect.left));
    const overlapY = Math.max(0, Math.min(videoRect.bottom, cardRect.bottom) - Math.max(videoRect.top, cardRect.top));
    const overlap = overlapX * overlapY;
    const cardArea = Math.max(1, cardRect.width * cardRect.height);
    const centerX = videoRect.left + videoRect.width / 2;
    const centerY = videoRect.top + videoRect.height / 2;
    const centerInside = centerX >= cardRect.left && centerX <= cardRect.right && centerY >= cardRect.top && centerY <= cardRect.bottom;
    return overlap / cardArea + (centerInside ? 1 : 0);
  }

  function findCardAuthor(lines) {
    const authorLine = lines.find((line) => /^@/.test(line)) || lines.find((line) => /@\S+/.test(line));
    return normalizeAuthorText(authorLine || "");
  }

  function normalizeAuthorText(value) {
    return String(value || "")
      .split(/[\u00b7\u2022]/)[0]
      .replace(/^@+/, "")
      .trim()
      .slice(0, 24);
  }

  function findCardLike(lines) {
    const likeLine = lines.find((line) => isLikeCountText(line));
    return normalizeLikeText(likeLine || "");
  }

  function findCardTitle(lines) {
    const titleLine = lines.find((line) => {
      const text = String(line || "").trim();
      if (text.length < 2) return false;
      if (/^\d{1,2}:\d{2}$/.test(text)) return false;
      if (isLikeCountText(text) || /^@/.test(text)) return false;
      if (/^[\u00b7\u2022]?\s*(?:\d{4}[-/.年])?\d{1,2}(?:月|[-/.])\d{1,2}日?$/.test(text)) return false;
      return !/^(?:广告|置顶|搜索|关注|喜欢|分享)$/.test(text);
    });
    return normalizeVideoTitle(titleLine || "");
  }

  function normalizeVideoTitle(value) {
    return String(value || "")
      .replace(/\s+/g, " ")
      .replace(/\s*(?:展开|收起)\s*$/u, "")
      .trim()
      .slice(0, 500);
  }

  function normalizeLikeText(value) {
    const text = String(value || "").trim().replace(/\s+/g, "");
    if (!text || !isLikeCountText(text)) return "";
    return text.endsWith("\u8d5e") ? text : `${text}\u8d5e`;
  }

  function readPrimaryVideoMeta() {
    const video = pickPrimaryVideo();
    return video ? readVideoMeta(video) : {};
  }

  function readMediaResourceKey(media) {
    if (!(media instanceof HTMLMediaElement)) return "";
    return resourceKey(media.currentSrc || media.src || media.querySelector?.("source")?.src || "");
  }

  function readShellResourceKey(shell) {
    if (!(shell instanceof Element)) return "";
    const video = shell.matches?.("video") ? shell : shell.querySelector?.("video");
    return readMediaResourceKey(video);
  }

  function pickPrimaryVideo() {
    const active = document.querySelector('[data-e2e="feed-active-video"] video, [data-e2e="feed-item"] video');
    if (active instanceof HTMLVideoElement) return active;
    const videos = Array.from(document.querySelectorAll("video"))
      .map((video) => ({ video, rect: video.getBoundingClientRect() }))
      .filter(({ rect }) => rect.width > 90 && rect.height > 90 && rect.bottom > 0 && rect.top < window.innerHeight)
      .sort((left, right) => (right.rect.width * right.rect.height) - (left.rect.width * left.rect.height));
    return videos[0]?.video || null;
  }

  function buildContainerKey(shell) {
    if (!(shell instanceof Element)) return "";
    const attrNames = [
      "data-e2e-vid",
      "data-aweme-id",
      "data-video-id",
      "data-item-id",
      "data-id",
      "data-note-id",
      "data-post-id",
      "data-object-id"
    ];
    for (let depth = 0, node = shell; node && depth < 5; depth += 1, node = node.parentElement) {
      for (const name of attrNames) {
        const value = String(node.getAttribute?.(name) || "").trim();
        if (value) return `${name}:${value}`;
      }
      const classValue = String(node.className || "");
      const classMatch = classValue.match(/\bvideo_(\d{8,})\b/i);
      if (classMatch) return `video:${classMatch[1]}`;
      const link = node.querySelector?.('a[href*="/video/"], a[href*="/note/"]');
      const href = String(link?.getAttribute?.("href") || "").trim();
      const hrefMatch = href.match(/\/(?:video|note)\/(\d{8,})/i);
      if (hrefMatch) return `href:${hrefMatch[1]}`;
      if (node.id && !/^sliderVideo$/i.test(node.id)) return `id:${node.id}`;
    }
    if (isDetailPage()) {
      const modalId = new URL(location.href).searchParams.get("modal_id");
      if (modalId) return `modal:${modalId}`;
    }
    return "";
  }

  function readSourceTraceMeta(root) {
    const awemeId = findAwemeId(root);
    return {
      awemeId,
      url: resolveSourceTraceUrl(root, awemeId)
    };
  }

  function findAwemeId(root) {
    const fromLocation = extractAwemeId(location.href);
    const roots = [];
    let node = root instanceof Element ? root : null;
    for (let depth = 0; node && depth < 8; depth += 1, node = node.parentElement) roots.push(node);
    for (const current of roots) {
      for (const value of [
        current.id,
        current.className,
        current.getAttribute?.("data-e2e-vid"),
        current.getAttribute?.("data-aweme-id"),
        current.getAttribute?.("data-video-id"),
        current.getAttribute?.("data-item-id"),
        current.getAttribute?.("data-id"),
        current.getAttribute?.("data-note-id"),
        current.getAttribute?.("data-post-id"),
        current.getAttribute?.("data-object-id")
      ]) {
        const matched = extractAwemeId(value);
        if (matched) return matched;
      }
      const link = findSourceTraceLink(current, "");
      const fromLink = extractAwemeId(link);
      if (fromLink) return fromLink;
    }
    return fromLocation;
  }

  function resolveSourceTraceUrl(root, awemeId) {
    const link = findSourceTraceLink(root, awemeId);
    if (link) return link;
    if (awemeId) return buildAwemePageUrl(awemeId);
    return isUsableDouyinTraceUrl(location.href) ? stripHash(location.href) : "";
  }

  function findSourceTraceLink(root, awemeId) {
    if (!(root instanceof Element)) return "";
    const selector = [
      'a[href*="/video/"]',
      'a[href*="/note/"]',
      'a[href*="modal_id="]',
      'a[href*="/jingxuan/"]'
    ].join(",");
    const roots = [];
    let node = root;
    for (let depth = 0; node && depth < 8; depth += 1, node = node.parentElement) roots.push(node);
    for (const current of roots) {
      const links = Array.from(current.matches?.("a[href]") ? [current] : current.querySelectorAll(selector));
      const urls = links
        .map((link) => normalizeHttpUrl(link.getAttribute("href") || link.href || ""))
        .filter(isUsableDouyinTraceUrl);
      if (awemeId) {
        const matched = urls.find((url) => url.includes(awemeId));
        if (matched) return stripHash(matched);
      }
      if (urls[0]) return stripHash(urls[0]);
    }
    return "";
  }

  function buildAwemePageUrl(awemeId) {
    return `https://www.douyin.com/video/${awemeId}`;
  }

  function isUsableDouyinTraceUrl(url) {
    try {
      const parsed = new URL(url, location.href);
      if (!/(^|\.)douyin\.com$/i.test(parsed.hostname)) return false;
      return /\/(video|note|jingxuan)\b/i.test(parsed.pathname) || parsed.searchParams.has("modal_id");
    } catch {
      return false;
    }
  }

  function extractAwemeId(value) {
    const match = String(value || "").match(/\d{8,}/);
    return match ? match[0] : "";
  }

  function normalizeHttpUrl(value) {
    try {
      return new URL(String(value || ""), location.href).href;
    } catch {
      return "";
    }
  }

  function stripHash(url) {
    try {
      const parsed = new URL(url, location.href);
      parsed.hash = "";
      return parsed.href;
    } catch {
      return String(url || "").split("#")[0];
    }
  }

  function resourceKey(url) {
    if (!url || BLOCKED_SCHEMES.test(url)) return "";
    try {
      const parsed = new URL(url);
      return `${parsed.origin}${parsed.pathname}`;
    } catch {
      return String(url || "").split("?")[0];
    }
  }

  function isLikeCountText(value) {
    const text = String(value || "").trim();
    if (!text || /^\d{1,2}:\d{2}$/.test(text)) return false;
    return /^(?:\d+(?:\.\d+)?(?:\u4e07|\u4ebf)?|\d{1,3}(?:,\d{3})+)(?:\u8d5e)?$/.test(text);
  }

  function absolutize(rawUrl) {
    if (!rawUrl) {
      return "";
    }
    try {
      return new URL(rawUrl, location.href).href;
    } catch {
      return "";
    }
  }

  function normalizeDimension(value) {
    const numeric = Math.round(Number(value || 0));
    return Number.isFinite(numeric) && numeric > 0 ? numeric : 0;
  }

  function extractFileName(rawUrl) {
    try {
      const pathname = new URL(String(rawUrl || ""), location.href).pathname;
      const fileName = pathname.split("/").filter(Boolean).pop() || "";
      return decodeURIComponent(fileName).slice(0, 160);
    } catch {
      return "";
    }
  }

  function getExtension(rawUrl) {
    const fileName = extractFileName(rawUrl).toLowerCase();
    const match = fileName.match(/\.([a-z0-9]{2,8})$/i);
    return match ? match[1] : "";
  }

  function parseSrcset(srcset = "") {
    return srcset
      .split(",")
      .map((entry) => entry.trim().split(/\s+/)[0])
      .filter(Boolean);
  }

  function parseCssUrls(value) {
    const matches = [];
    const pattern = /url\((["']?)(.*?)\1\)/gi;
    let match = pattern.exec(value);
    while (match) {
      matches.push(match[2]);
      match = pattern.exec(value);
    }
    return matches;
  }
})();
