(() => {
  "use strict";

  if (window.top !== window || window.__stonkTikTokShopViewer) return;
  window.__stonkTikTokShopViewer = true;

  const EVENT_NAME = "STONK_TIKTOK_SHOP_PAGE_DATA";
  const state = { enabled: true, products: new Map(), videos: new Map(), currentVideoId: "", panelOpen: false, renderSignature: "" };
  const fetchingWrappers = new WeakSet();
  const playerByWrapper = new WeakMap();
  const mediaByVideoUrl = new Map();
  const WRAPPER_SELECTOR = '[class*="DivVideoWrapper"], [class*="DivVideoContainer"], [data-e2e="recommend-list-item-container"], .video-container';

  const ICON_PATHS = Object.freeze({
    bag: '<path d="M5 8h14l1 13H4L5 8Z"/><path d="M9 9V6a3 3 0 0 1 6 0v3"/>',
    package: '<path d="m12 2 9 5-9 5-9-5 9-5Z"/><path d="m3 7 9 5 9-5M3 7v10l9 5 9-5V7M12 12v10"/>',
    close: '<path d="M6 6l12 12M18 6 6 18"/>',
    external: '<path d="M14 4h6v6M20 4 11 13M20 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5"/>',
  });
  const shopIcon = name => `<svg class="stonk-shop-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${ICON_PATHS[name] || ICON_PATHS.bag}</svg>`;

  function html(value) {
    return String(value ?? "").replace(/[&<>'"]/g, char => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#39;", '"': "&quot;" })[char]);
  }

  function internalUrl(value) {
    try {
      const url = new URL(String(value || ""), location.href);
      return /(^|\.)tiktok\.com$|(^|\.)tiktokcdn(?:-us)?\.com$|(^|\.)byteoversea\.com$|(^|\.)ibytedtos\.com$|(^|\.)muscdn\.com$|(^|\.)tikwm\.com$/i.test(url.hostname) ? url.href : "";
    } catch {
      return "";
    }
  }

  function tikwmMediaUrl(value) {
    const raw = String(value || "").trim();
    if (!raw) return "";
    if (raw.startsWith("/")) {
      try { return new URL(raw, "https://tikwm.com").href; } catch { return ""; }
    }
    return internalUrl(raw);
  }

  function videoIdFromUrl(value = location.href) {
    return String(value).match(/\/(?:video|v)\/(\d{15,25})/i)?.[1] || "";
  }

  function currentVideoId() {
    const fromPage = videoIdFromUrl();
    if (fromPage) return fromPage;
    const visible = Array.from(document.querySelectorAll(WRAPPER_SELECTOR)).find(element => {
      const rect = element.getBoundingClientRect();
      return rect.height > 0 && rect.top < innerHeight * 0.65 && rect.bottom > innerHeight * 0.35;
    });
    const anchor = visible?.querySelector('a[href*="/video/"], a[href*="/v/"]');
    return videoIdFromUrl(anchor?.href || "");
  }

  function mergePayload(payload = {}) {
    for (const video of Array.isArray(payload.videos) ? payload.videos : []) {
      const id = String(video?.id || "");
      if (!id) continue;
      const urls = (Array.isArray(video.urls) ? video.urls : []).map(internalUrl).filter(Boolean);
      if (urls.length) state.videos.set(id, { id, urls });
    }
    for (const product of Array.isArray(payload.products) ? payload.products : []) {
      const id = String(product?.id || "");
      if (!id) continue;
      state.products.set(id, {
        id,
        title: String(product.title || `Sản phẩm ${id}`),
        href: internalUrl(product.href) || `https://www.tiktok.com/view/product/${encodeURIComponent(id)}`,
        image: internalUrl(product.image),
        price: String(product.price || ""),
        seller: String(product.seller || ""),
        videoId: String(product.videoId || ""),
      });
    }
    scanDomProducts();
    recoverBlockedVideos();
    render();
  }

  function scanDomProducts() {
    document.querySelectorAll('a[href*="/view/product/"], a[href*="/product/"]').forEach(anchor => {
      const href = internalUrl(anchor.href);
      if (!href) return;
      const id = href.match(/\/(?:view\/)?product\/(\d{8,25})/i)?.[1] || new URL(href).searchParams.get("product_id") || "";
      if (!id) return;
      const container = anchor.closest('[data-e2e], article, li, [class*="Product"], [class*="product"]') || anchor;
      const image = container.querySelector("img")?.currentSrc || container.querySelector("img")?.src || "";
      const old = state.products.get(id) || {};
      state.products.set(id, {
        id,
        title: old.title || String(anchor.getAttribute("aria-label") || anchor.textContent || `Sản phẩm ${id}`).trim(),
        href,
        image: old.image || internalUrl(image),
        price: old.price || "",
        seller: old.seller || "",
        videoId: old.videoId || currentVideoId(),
      });
    });
  }

  function productsForCurrentVideo() {
    const id = currentVideoId();
    const all = Array.from(state.products.values());
    const exact = id ? all.filter(product => product.videoId === id) : [];
    return exact.length ? exact : all.filter(product => !product.videoId || product.videoId === id);
  }

  function nativeVideoUrl(id) {
    const known = state.videos.get(id)?.urls || [];
    return known.find(url => /\.(?:mp4|m3u8)(?:\?|$)/i.test(url)) || known[0] || "";
  }

  function recoverBlockedVideos() {
    if (!state.enabled) return;
    for (const wrapper of document.querySelectorAll(WRAPPER_SELECTOR)) {
      if (wrapper.dataset.stonkShopFixed === "1" || fetchingWrappers.has(wrapper)) continue;
      if (wrapper.querySelector('[class*="DivImageContainer"]') && !wrapper.querySelector("video")) continue;
      const rect = wrapper.getBoundingClientRect();
      if (!rect.height || rect.top < -500 || rect.bottom > innerHeight + 500) continue;
      const video = wrapper.querySelector("video");
      const blocked = !video || (!video.currentSrc && !video.src && !video.querySelector("source"));
      if (!blocked) continue;
      const anchor = wrapper.querySelector('a[href*="/video/"], a[href*="/v/"]');
      const targetUrl = String(anchor?.href || location.href).split("?")[0];
      const id = videoIdFromUrl(targetUrl);
      if (!id) continue;
      const nativeSource = nativeVideoUrl(id);

      const attachVideo = sources => {
        const candidates = (Array.isArray(sources) ? sources : [sources]).map(tikwmMediaUrl).filter(Boolean);
        if (!candidates.length) return;
        playerByWrapper.get(wrapper)?.host?.remove();
        const host = document.createElement("div");
        host.className = "stonk-shop-player-host";
        host.dataset.stonkShopInjected = "1";
        const shadow = host.attachShadow({ mode: "open" });
        shadow.innerHTML = `<style>
          :host{position:absolute;inset:0;z-index:2147483000;display:block;background:#000;border-radius:8px;overflow:hidden}
          video{display:block;width:100%;height:100%;object-fit:contain;background:#000}
          .note{position:absolute;left:10px;top:10px;padding:4px 7px;border-radius:999px;background:rgba(0,0,0,.55);color:#fff;font:600 10px/1.3 system-ui,sans-serif;pointer-events:none}
        </style><video controls autoplay loop playsinline preload="auto"></video><span class="note">STONK · TikTok Shop</span>`;
        const restored = shadow.querySelector("video");
        let sourceIndex = 0;
        const loadSource = () => {
          if (sourceIndex >= candidates.length) return;
          restored.src = candidates[sourceIndex];
          restored.load();
          restored.play().catch(() => {});
        };
        restored.addEventListener("error", () => {
          sourceIndex += 1;
          loadSource();
        });
        restored.addEventListener("canplay", () => restored.play().catch(() => {}));
        if (getComputedStyle(wrapper).position === "static") wrapper.style.position = "relative";
        wrapper.querySelector(".stonk-shop-video-loader")?.remove();
        wrapper.appendChild(host);
        if (video) video.remove();
        wrapper.dataset.stonkShopFixed = "1";
        playerByWrapper.set(wrapper, { host, video: restored, targetUrl });
        loadSource();
      };

      if (nativeSource) {
        attachVideo([nativeSource]);
        continue;
      }

      const remembered = mediaByVideoUrl.get(targetUrl);
      if (remembered?.length) {
        attachVideo(remembered);
        continue;
      }

      fetchingWrappers.add(wrapper);
      if (getComputedStyle(wrapper).position === "static") wrapper.style.position = "relative";
      const loader = document.createElement("div");
      loader.className = "stonk-shop-video-loader";
      loader.innerHTML = `<i aria-hidden="true"></i><span>Đang mở video TikTok Shop…</span>`;
      wrapper.appendChild(loader);
      chrome.runtime.sendMessage({ type: "STONK_TIKTOK_SHOP_MEDIA_FETCH", url: targetUrl }, response => {
        const error = chrome.runtime.lastError;
        const sources = [response?.data?.hdplay, response?.data?.play, response?.data?.wmplay].map(tikwmMediaUrl).filter(Boolean);
        if (!error && response?.ok && sources.length) {
          mediaByVideoUrl.set(targetUrl, sources);
          attachVideo(sources);
          return;
        }
        loader.innerHTML = `<span>Không mở được video. Bấm để thử lại.</span>`;
        loader.classList.add("is-error");
        loader.addEventListener("click", () => {
          loader.remove();
          fetchingWrappers.delete(wrapper);
          recoverBlockedVideos();
        }, { once: true });
      });
    }
  }

  function ensureUi() {
    if (document.getElementById("stonkShopViewer")) return;
    const root = document.createElement("section");
    root.id = "stonkShopViewer";
    root.innerHTML = `
      <button type="button" class="stonk-shop-trigger" aria-expanded="false" aria-controls="stonkShopPanel">
        <span aria-hidden="true">${shopIcon("bag")}</span><b>Xem sản phẩm</b><em id="stonkShopCount">0</em>
      </button>
      <aside id="stonkShopPanel" class="stonk-shop-panel" hidden aria-label="Sản phẩm gắn trong video">
        <header><div><strong>Sản phẩm gắn trong video</strong><small>Dữ liệu đang hiển thị trực tiếp từ trang TikTok</small></div><button type="button" data-stonk-shop-close aria-label="Đóng">${shopIcon("close")}</button></header>
        <div class="stonk-shop-list" id="stonkShopList"></div>
      </aside>`;
    document.documentElement.appendChild(root);
    root.querySelector(".stonk-shop-trigger").addEventListener("click", () => {
      state.panelOpen = !state.panelOpen;
      render();
    });
    root.querySelector("[data-stonk-shop-close]").addEventListener("click", () => {
      state.panelOpen = false;
      render();
    });
  }

  function render() {
    ensureUi();
    const root = document.getElementById("stonkShopViewer");
    const list = document.getElementById("stonkShopList");
    const panel = document.getElementById("stonkShopPanel");
    const trigger = root.querySelector(".stonk-shop-trigger");
    const products = productsForCurrentVideo();
    const hasShopContext = state.enabled && (products.length > 0 || Boolean(document.querySelector('a[href*="/view/product/"], a[href*="/product/"]')));
    root.hidden = !hasShopContext;
    panel.hidden = !state.panelOpen;
    trigger.setAttribute("aria-expanded", String(state.panelOpen));
    document.getElementById("stonkShopCount").textContent = String(products.length);
    const signature = JSON.stringify([state.currentVideoId, state.panelOpen, products]);
    if (signature === state.renderSignature) return;
    state.renderSignature = signature;
    list.innerHTML = products.length ? products.map(product => `
      <a class="stonk-shop-card" href="${html(product.href)}" target="_blank" rel="noopener">
        ${product.image ? `<img src="${html(product.image)}" alt="" loading="lazy">` : `<span class="stonk-shop-image" aria-hidden="true">${shopIcon("package")}</span>`}
        <span><strong>${html(product.title)}</strong>${product.seller ? `<small>${html(product.seller)}</small>` : ""}${product.price ? `<b>${html(product.price)}</b>` : ""}</span>
        <em>Xem ${shopIcon("external")}</em>
      </a>`).join("") : `<div class="stonk-shop-empty">TikTok chưa tải thông tin giỏ hàng của video này. Hãy phát video hoặc mở biểu tượng giỏ hàng trên TikTok rồi thử lại.</div>`;
  }

  window.addEventListener("message", event => {
    if (event.source === window && event.origin === location.origin && event.data?.type === EVENT_NAME) {
      mergePayload(event.data.payload);
    }
  });
  document.addEventListener("keydown", event => {
    if (event.key === "Escape" && state.panelOpen) {
      state.panelOpen = false;
      render();
    }
  });

  let scheduled = 0;
  const refresh = () => {
    clearTimeout(scheduled);
    scheduled = setTimeout(() => {
      if (!state.enabled) {
        const root = document.getElementById("stonkShopViewer");
        if (root) root.hidden = true;
        return;
      }
      const id = currentVideoId();
      if (id !== state.currentVideoId) state.currentVideoId = id;
      scanDomProducts();
      recoverBlockedVideos();
      render();
      window.postMessage({ type: "STONK_TIKTOK_SHOP_SCAN" }, location.origin);
    }, 250);
  };
  new MutationObserver(records => {
    const onlyOwnUi = records.every(record => record.target instanceof Element && record.target.closest("#stonkShopViewer"));
    if (!onlyOwnUi) refresh();
  }).observe(document.documentElement, { childList: true, subtree: true });
  setInterval(refresh, 1500);
  chrome.storage.local.get({ stonkTikTokShopViewerEnabled: true }, stored => {
    state.enabled = stored.stonkTikTokShopViewerEnabled !== false;
    refresh();
  });
  chrome.storage.onChanged.addListener((changes, area) => {
    if (area !== "local" || !changes.stonkTikTokShopViewerEnabled) return;
    state.enabled = changes.stonkTikTokShopViewerEnabled.newValue !== false;
    state.panelOpen = false;
    state.renderSignature = "";
    refresh();
  });
})();
