(() => {
  const cleanstreamHost = location.hostname.toLowerCase();
  const supportedPage = false;
  const state = {
    settings: null,
    host: location.hostname,
    found: new Set(),
    candidates: new Set(),
    deepScan: false,
    pageUrl: location.href,
    dismissedUrl: null,
    active: supportedPage,
  };
  const suspicious =
    /(pop|ad[sx]?|click|track|promo|offer|affiliate|redirect|casino|bet|notification)/i;
  const adSignal =
    /(?:^|[\s_./?&=-])(vast|vmap|preroll|midroll|postroll|video-?ad|advert|ads?|promo|sponsor)(?:$|[\s_./?&=-])/i;
  const providerSignal = /(streamwish|filemoon|vidhide|voesx|voe(?=[._\/-])|doodstream|dood(?=[._\/-])|medixiru|streamtape|mixdrop|filelions|lulustream)/i;
  const isProviderUrl = (raw) => { try { return providerSignal.test(new URL(raw, location.href).hostname); } catch { return false; } };
  const isForbiddenBridge = (raw) => { try { const h=new URL(raw,location.href).hostname.toLowerCase(); return h==="player.repelis24.life"||h.endsWith(".player.repelis24.life"); } catch { return false; } };
  const providerRefs = new Set();
  const reportBlocked = (count = 1) =>
    chrome.runtime.sendMessage({ type: "ADS_BLOCKED", count }).catch(() => {});
  let safeScanRunning = false;
  let protectedMode = false;
  let startFull = () => {};
  let analyzeSurface = null;

  function removeAnalyzeSurface() {
    if (!analyzeSurface) return;
    window.removeEventListener("message", analyzeSurface.onMessage);
    analyzeSurface.host.remove();
    analyzeSurface = null;
  }

  async function settings() {
    const defaults = {
      enabled: true,
      blockPopups: true,
      removeOverlays: true,
      detectVideos: true,
      skipAds: true,
      showFoundNotice: true,
      aggressiveMode: false,
      allowlist: [],
    };
    state.settings = await chrome.storage.local.get(defaults);
    return state.settings;
  }
  function allowed() {
    return (state.settings?.allowlist || []).some(
      (x) => state.host === x || state.host.endsWith(`.${x}`),
    );
  }
  function isAd(item, element) {
    const context = `${item.url} ${item.type || ""} ${element?.id || ""} ${element?.className || ""} ${element?.closest?.("[class],[id]")?.className || ""}`;
    return (
      adSignal.test(context) ||
      /doubleclick|googlesyndication|googleadservices|adnxs|exoclick|trafficjunky|adsterra|propellerads/i.test(
        context,
      )
    );
  }
  function renderInlineCatalog(box, catalog) {
    const options = catalog?.options || [],
      series = catalog?.series;
    const panel = box.firstElementChild;
    panel.classList.add("cs-catalog");
    panel.classList.toggle("cs-series-catalog", Boolean(series));
    panel.innerHTML =
      '<button class="cs-dismiss">×</button><div class="cs-post"><img class="cs-poster"><div><small class="cs-kind">Publicación analizada</small><b class="cs-title"></b><p class="cs-description"></p></div></div><div class="cs-summary"></div><div class="cs-seasons"></div><div class="cs-options"></div>';
    panel.querySelector(".cs-dismiss").onclick = () => box.remove();
    panel.querySelector(".cs-title").textContent =
      catalog?.title || document.title;
    panel.querySelector(".cs-description").textContent =
      catalog?.description || "Selecciona una opción de reproducción.";
    const poster = panel.querySelector(".cs-poster");
    if (catalog?.image) poster.src = catalog.image;
    else poster.remove();
    const list = panel.querySelector(".cs-options"),
      seasonsBox = panel.querySelector(".cs-seasons");
    if (series) {
      panel.querySelector(".cs-kind").textContent = "Serie detectada";
      const episodes = series.episodes || [],
        seasons = [...new Set(episodes.map((x) => x.season ?? 1))];
      panel.querySelector(".cs-summary").textContent =
        `${seasons.length} temporada${seasons.length === 1 ? "" : "s"} · ${episodes.length} capítulo${episodes.length === 1 ? "" : "s"}`;
      seasons.forEach((season, index) => {
        const button = document.createElement("button");
        button.textContent = `Temporada ${season}`;
        button.className = index ? "" : "active";
        button.onclick = () => {
          seasonsBox
            .querySelectorAll("button")
            .forEach((x) => x.classList.toggle("active", x === button));
          list
            .querySelectorAll("[data-season]")
            .forEach((x) => (x.hidden = Number(x.dataset.season) !== season));
        };
        seasonsBox.append(button);
      });
      episodes.forEach((episode, index) => {
        const card = document.createElement("article");
        card.className = "cs-option cs-episode";
        card.dataset.season = episode.season ?? 1;
        card.hidden = (episode.season ?? 1) !== seasons[0];
        const number = document.createElement("span");
        number.textContent = episode.episode || index + 1;
        const data = document.createElement("div");
        const name = document.createElement("b");
        name.textContent =
          episode.label || `Capítulo ${episode.episode || index + 1}`;
        const meta = document.createElement("small");
        meta.textContent = episode.options?.length
          ? `${episode.options.length} opción${episode.options.length === 1 ? "" : "es"} disponible${episode.options.length === 1 ? "" : "s"}`
          : "Fuente pendiente";
        data.append(name, meta);
        const select = document.createElement("select");
        (episode.options || []).forEach((option, i) => {
          const item = document.createElement("option");
          item.value = i;
          item.textContent = option.provider;
          select.append(item);
        });
        const button = document.createElement("button");
        button.textContent = "Ver capítulo";
        button.disabled = !episode.options?.length;
        button.onclick = () => {
          const selected = episode.options[Number(select.value) || 0];
          if (selected)
            chrome.runtime.sendMessage({
              type: "OPEN_PROTECTED_PLAYER",
              url: selected.url,
              title: episode.label || catalog.title,
              image: episode.image || catalog.image || "",
              postUrl: episode.url,
              series: { ...series, currentIndex: index },
            });
        };
        card.append(number, data, select, button);
        list.append(card);
      });
      return;
    }
    seasonsBox.remove();
    panel.querySelector(".cs-summary").textContent =
      `${options.length} opción${options.length === 1 ? "" : "es"} encontrada${options.length === 1 ? "" : "s"}`;
    if (!options.length) {
      list.innerHTML =
        '<div class="cs-empty">No se encontraron enlaces de StreamWish, FileMoon, VidHide o VoeSX, incluso después de revisar la pestaña Latino.</div>';
      return;
    }
    options.forEach((item, index) => {
      const card = document.createElement("article");
      card.className = "cs-option";
      const number = document.createElement("span");
      number.textContent = index + 1;
      const data = document.createElement("div");
      const name = document.createElement("b");
      name.textContent = `Opción ${index + 1} · ${item.provider}`;
      const url = document.createElement("small");
      url.textContent = item.url;
      data.append(name, url);
      const button = document.createElement("button");
      button.textContent = "Ver video";
      button.onclick = () =>
        chrome.runtime.sendMessage({
          type: "OPEN_PROTECTED_PLAYER",
          url: item.url,
          title: catalog?.title || document.title,
          image: catalog?.image || "",
          postUrl: catalog?.sourceUrl || location.href,
        });
      card.append(number, data, button);
      list.append(card);
    });
  }
  function renderSeriesCatalog(box, catalog) {
    if (!catalog?.series) return renderInlineCatalog(box, catalog);
    const series = catalog.series,
      episodes = series.episodes || [],
      seasons = [...new Set(episodes.map((x) => x.season ?? 1))];
    const panel = box.firstElementChild;
    panel.className = "cs-catalog cs-series-v2";
    panel.innerHTML =
      '<button class="cs-dismiss">×</button><div class="cs-post"><img class="cs-poster"><div><small>SERIE DETECTADA</small><b class="cs-title"></b><p class="cs-description"></p></div></div><div class="cs-series-toolbar"><div><b class="cs-count"></b><small>Selecciona un capítulo y luego una opción de reproducción.</small></div><label class="cs-season-picker"><span>Temporada</span><select></select></label></div><div class="cs-episode-list"></div>';
    panel.querySelector(".cs-dismiss").onclick = () => box.remove();
    panel.querySelector(".cs-title").textContent =
      catalog.title || document.title;
    panel.querySelector(".cs-description").textContent =
      catalog.description || "Selecciona un capítulo para ver sus opciones.";
    const poster = panel.querySelector(".cs-poster");
    if (catalog.image) poster.src = catalog.image;
    else poster.remove();
    panel.querySelector(".cs-count").textContent =
      `${seasons.length} temporada${seasons.length === 1 ? "" : "s"} · ${episodes.length} capítulo${episodes.length === 1 ? "" : "s"}`;
    const picker = panel.querySelector(".cs-season-picker"),
      select = picker.querySelector("select"),
      list = panel.querySelector(".cs-episode-list");
    if (seasons.length < 2) picker.hidden = true;
    seasons.forEach((season) => {
      const option = document.createElement("option");
      option.value = season;
      option.textContent = `Temporada ${season}`;
      select.append(option);
    });
    episodes.forEach((episode, index) => {
      const details = document.createElement("details");
      details.className = "cs-episode-card";
      details.dataset.season = episode.season ?? 1;
      const summary = document.createElement("summary");
      const number = document.createElement("span");
      number.className = "cs-episode-number";
      number.textContent = episode.episode || index + 1;
      const info = document.createElement("span");
      info.className = "cs-episode-info";
      const title = document.createElement("b");
      title.textContent =
        episode.label || `Capítulo ${episode.episode || index + 1}`;
      const total = document.createElement("small");
      total.textContent = episode.options?.length
        ? `${episode.options.length} opción${episode.options.length === 1 ? "" : "es"} de reproducción`
        : "No se encontraron opciones";
      info.append(title, total);
      const arrow = document.createElement("span");
      arrow.className = "cs-episode-arrow";
      arrow.textContent = "⌄";
      summary.append(number, info, arrow);
      const providers = document.createElement("div");
      providers.className = "cs-provider-options";
      if (!episode.options?.length) {
        providers.innerHTML =
          "<small>Este capítulo todavía no tiene una fuente compatible.</small>";
      } else
        episode.options.forEach((source, sourceIndex) => {
          const button = document.createElement("button");
          button.innerHTML = `<span>Opción ${sourceIndex + 1}</span><b>${source.provider}</b><i>Reproducir →</i>`;
          button.onclick = () =>
            chrome.runtime.sendMessage({
              type: "OPEN_PROTECTED_PLAYER",
              url: source.url,
              title: episode.label || catalog.title,
              image: episode.image || catalog.image || "",
              postUrl: episode.url,
              series: { ...series, currentIndex: index },
            });
          providers.append(button);
        });
      details.append(summary, providers);
      list.append(details);
    });
    const showSeason = (season) => {
      list.querySelectorAll("[data-season]").forEach((card) => {
        card.hidden = Number(card.dataset.season) !== season;
        card.open = false;
      });
      const first = [...list.querySelectorAll("[data-season]")].find(
        (card) => !card.hidden,
      );
      if (first) first.open = true;
    };
    select.onchange = () => showSeason(Number(select.value));
    showSeason(seasons[0]);
  }
  function renderSeriesWithSeasonMenu(box, catalog) {
    renderSeriesCatalog(box, catalog);
    const seasons = [
        ...new Set((catalog?.series?.episodes || []).map((x) => x.season ?? 1)),
      ],
      picker = box.querySelector(".cs-season-picker"),
      select = picker?.querySelector("select");
    if (seasons.length < 2 || !picker || !select) return;
    const menu = document.createElement("details");
    menu.className = "cs-season-menu";
    const summary = document.createElement("summary");
    summary.textContent = `Temporadas · Temporada ${seasons[0]}`;
    const choices = document.createElement("div");
    seasons.forEach((season) => {
      const button = document.createElement("button");
      button.textContent = `Temporada ${season}`;
      button.classList.toggle("active", season === seasons[0]);
      button.onclick = () => {
        select.value = String(season);
        select.dispatchEvent(new Event("change"));
        choices
          .querySelectorAll("button")
          .forEach((x) => x.classList.toggle("active", x === button));
        summary.textContent = `Temporadas · Temporada ${season}`;
        menu.open = false;
      };
      choices.append(button);
    });
    menu.append(summary, choices);
    picker.replaceWith(menu);
  }
  function addAnalyzePrompt() {
    if (
      window !== top ||
      protectedMode ||
      state.dismissedUrl === location.href ||
      analyzeSurface
    )
      return;
    const token = crypto.randomUUID?.() || `${Date.now()}-${Math.random()}`;
    const host = document.createElement(`cleanstream-${token.replace(/[^a-z0-9]/gi, "").slice(0, 12)}`);
    const shadow = host.attachShadow({ mode: "closed" });
    host.style.cssText =
      "all:initial!important;position:fixed!important;top:16px!important;right:16px!important;width:min(390px,calc(100vw - 24px))!important;height:258px!important;z-index:2147483647!important;display:block!important;pointer-events:auto!important;transition:width .22s ease,height .22s ease!important;contain:layout style paint!important;";
    const style = document.createElement("style");
    style.textContent =
      ":host{color-scheme:dark!important}iframe{display:block!important;width:100%!important;height:100%!important;border:0!important;background:transparent!important;border-radius:16px!important;box-shadow:0 18px 55px #0009!important}";
    const frame = document.createElement("iframe");
    frame.title = "Analizador protegido de CleanStream";
    frame.src = `${chrome.runtime.getURL("analyze-frame.html")}?token=${encodeURIComponent(token)}`;
    frame.setAttribute("allow", "autoplay; fullscreen");
    shadow.append(style, frame);
    document.documentElement.append(host);
    const extensionOrigin = new URL(chrome.runtime.getURL("/")).origin;
    const onMessage = (event) => {
      if (
        event.source !== frame.contentWindow ||
        event.origin !== extensionOrigin ||
        event.data?.token !== token
      )
        return;
      if (event.data.type === "CLEANSTREAM_CLOSE") {
        state.dismissedUrl = location.href;
        removeAnalyzeSurface();
      }
      if (event.data.type === "CLEANSTREAM_RESIZE") {
        const resultMode = event.data.mode === "result";
        host.style.setProperty(
          "width",
          resultMode
            ? "min(620px, calc(100vw - 24px))"
            : "min(390px, calc(100vw - 24px))",
          "important",
        );
        const maximum = resultMode ? Math.round(innerHeight * 0.72) : 310;
        const requested = Math.max(
          180,
          Math.min(maximum, Number(event.data.height) || 258),
        );
        host.style.setProperty("height", `${requested}px`, "important");
      }
    };
    analyzeSurface = { host, frame, onMessage };
    window.addEventListener("message", onMessage);
  }
  function maybeShowAnalyze() {
    if (protectedMode || window !== top) return;
    const selector =
      'iframe[src*="player" i],iframe[src*="embed" i],embed[src],object[data],a[href*="player" i],a[href*="embed" i],a[href*="streamwish" i],a[href*="filemoon" i],a[href*="vidhide" i],a[href*="voesx" i],a[href*="voe." i],a[href*="voe-" i],a[href*="doodstream" i],a[href*="dood." i],a[href*="dood-" i],a[href*="medixiru" i],a[href*="streamtape" i],a[href*="mixdrop" i],a[href*="filelions" i],a[href*="lulustream" i]';
    const episodeLinks = [...document.querySelectorAll("a[href]")].filter((a) =>
        /(cap[ií]tulo|episodio|episode|temporada|season|\bS\d+E\d+\b)/i.test(
          `${a.textContent || ""} ${a.href}`,
        ),
      ),
      seriesPage = /\/series\/[^/]+\/?$/i.test(location.pathname),
      seasonSelector = [...document.querySelectorAll("select")].some(
        (select) =>
          select.options.length > 0 &&
          [...select.options].some((option) =>
            /(?:temporada|season)\s*\d+/i.test(option.textContent || ""),
          ),
      ),
      nextData = document.getElementById("__NEXT_DATA__")?.textContent || "",
      embeddedSeries =
        seriesPage &&
        /"seasons"\s*:\s*\[/i.test(nextData) &&
        /"episodes"\s*:\s*\[/i.test(nextData);
    if (
      providerRefs.size ||
      document.querySelector(selector) ||
      episodeLinks.length >= 2 ||
      (seriesPage && (seasonSelector || embeddedSeries))
    )
      addAnalyzePrompt();
  }
  function maybeShowResume() {
    if (window !== top || document.getElementById("cleanstream-resume-banner"))
      return;
    chrome.runtime.sendMessage(
      { type: "GET_RESUME_SUGGESTION" },
      (response) => {
        if (!response?.show) return;
        const item = response.last,
          box = document.createElement("div");
        box.id = "cleanstream-resume-banner";
        box.innerHTML =
          '<div><span class="cs-resume-icon">▶</span><span class="cs-resume-copy"><b></b><small>Continúa tu reproducción anterior o abre tu catálogo guardado.</small></span><button class="cs-resume-primary">Continuar viendo</button><button class="cs-resume-catalog">Mi catálogo</button><button class="cs-resume-close" aria-label="Cerrar">×</button></div>';
        box.querySelector("b").textContent =
          item?.title || "Tu catálogo CleanStream está listo";
        const primary = box.querySelector(".cs-resume-primary");
        if (!item) primary.remove();
        else
          primary.onclick = () => {
            chrome.runtime.sendMessage({ type: "CONTINUE_LAST_VIDEO", item });
            box.remove();
          };
        box.querySelector(".cs-resume-catalog").onclick = () => {
          chrome.runtime.sendMessage({ type: "OPEN_USER_CATALOG" });
          box.remove();
        };
        box.querySelector(".cs-resume-close").onclick = () => box.remove();
        document.documentElement.append(box);
      },
    );
  }
  async function runSafeScan() {
    if (safeScanRunning) return;
    safeScanRunning = true;
    let actions = 0,
      rounds = 0,
      clickedSkip = false,
      playerStarted = false;
    const used = new WeakSet(),
      exact =
        /^(play(?: video)?|reproducir(?: video)?|click to play|haz clic para reproducir|continuar|continue|skip|saltar|saltar anuncio|skip ad|cerrar anuncio|close ad)$/i,
      countdown =
        /^(skip after|skip in|saltar en|podrás saltar|puedes saltar)\b/i,
      voePage = /(?:voesx|voe(?=[._\/-]))/i.test(location.href),
      visible = (el) => {
        const r = el.getBoundingClientRect(),
          style = getComputedStyle(el);
        return (
          r.width > 20 &&
          r.height > 15 &&
          r.bottom > 0 &&
          r.right > 0 &&
          style.display !== "none" &&
          style.visibility !== "hidden" &&
          Number(style.opacity) !== 0
        );
      };
    const timer = setInterval(() => {
      rounds++;
      const hls = [...state.found].filter((url) =>
        /\.m3u8(?:[?#]|$)/i.test(url),
      );
      if (hls.length || rounds > 35) {
        clearInterval(timer);
        safeScanRunning = false;
        chrome.runtime.sendMessage({
          type: "SAFE_SCAN_PROGRESS",
          status: hls.length ? "found" : "not-found",
          providers: [...providerRefs],
          media: hls,
          actions,
          clickedSkip,
        });
        return;
      }
      if (voePage && !playerStarted && rounds <= 10) {
        const selectors =
            '.jw-display-icon-container,.jw-icon-display,.vjs-big-play-button,.plyr__control--overlaid,[data-plyr="play"],button[aria-label="Play" i],button[title="Play" i],button[aria-label="Reproducir" i]',
          start = [...document.querySelectorAll(selectors)].find(
            (el) =>
              visible(el) &&
              !el.closest(
                '[class*="advert" i],[class*="video-ad" i],[class*="preroll" i],[id*="advert" i],[id*="video-ad" i]',
              ),
          );
        if (start) {
          playerStarted = true;
          used.add(start);
          start.click();
          actions++;
          chrome.runtime.sendMessage({
            type: "SAFE_SCAN_PROGRESS",
            status: "starting-player",
            actions,
            clickedSkip,
          });
          scan();
          return;
        }
      }
      let waiting = false;
      const controls = [
        ...document.querySelectorAll('button,[role="button"],a'),
      ].filter((el) => {
        const label = (el.getAttribute("aria-label") || el.textContent || "")
          .trim()
          .replace(/\s+/g, " ");
        if (countdown.test(label)) waiting = true;
        return (
          !used.has(el) &&
          visible(el) &&
          !el.disabled &&
          el.getAttribute("aria-disabled") !== "true" &&
          exact.test(label) &&
          !suspicious.test(el.href || "")
        );
      });
      const next =
        controls.find((el) =>
          /^(skip|saltar|saltar anuncio|skip ad)$/i.test(
            (el.getAttribute("aria-label") || el.textContent || "").trim(),
          ),
        ) ||
        controls.find((el) =>
          /^(continuar|continue)$/i.test(
            (el.getAttribute("aria-label") || el.textContent || "").trim(),
          ),
        ) ||
        controls[0];
      if (next && actions < 10) {
        const label = (
          next.getAttribute("aria-label") ||
          next.textContent ||
          ""
        ).trim();
        used.add(next);
        next.click();
        actions++;
        if (/^(skip|saltar)/i.test(label)) clickedSkip = true;
        chrome.runtime.sendMessage({
          type: "SAFE_SCAN_PROGRESS",
          status: "searching",
          actions,
          clickedSkip,
        });
      } else if (waiting)
        chrome.runtime.sendMessage({
          type: "SAFE_SCAN_PROGRESS",
          status: "waiting-skip",
          actions,
        });
      scan();
    }, 1200);
  }
  function report(items) {
    const fresh = items.filter(
      (x) => !x.isAd && x.url && !state.found.has(x.url),
    );
    fresh.forEach((x) => state.found.add(x.url));
    if (fresh.length)
      chrome.runtime
        .sendMessage({ type: "FOUND_MEDIA", items: fresh })
        .catch(() => {});
  }
  function scan(root = document) {
    if (!state.settings?.detectVideos) return;
    const items = [];
    root
      .querySelectorAll?.(
        "video, video source, a[href], iframe[src], embed[src], object[data]",
      )
      .forEach((el) => {
        const raw = el.currentSrc || el.src || el.href || el.data;
        if (!raw) return;
        let url;
        try {
          url = new URL(raw, location.href).href;
        } catch {
          return;
        }
        if (isProviderUrl(url) && !isForbiddenBridge(url)) {
          providerRefs.add(url);
          chrome.runtime
            .sendMessage({
              type: "PROVIDERS_FOUND",
              urls: [...providerRefs],
              title: document.title,
            })
            .catch(() => {});
        }
        if (
          el.matches("video, video source") ||
          /\.(mp4|webm|m3u8|mpd)(?:[?#]|$)/i.test(url)
        ) {
          const item = {
            url,
            type: el.type || "",
            title: document.title,
            source: "page",
          };
          item.isAd = isAd(item, el);
          items.push(item);
        } else if (
          state.deepScan &&
          /(player|embed|stream|watch|video|media|play)/i.test(
            `${url} ${el.id || ""} ${el.className || ""}`,
          ) &&
          !isAd({ url }, el)
        )
          state.candidates.add(url);
      });
    root.querySelectorAll?.("script").forEach((script) => {
      const text = (script.textContent || "").replace(/\\\//g, "/");
      const matches =
        text.match(
          /https?:\/\/[^\s"'<>]+(?:streamwish|filemoon|vidhide|voesx|voe(?:\.|-)|doodstream|dood(?:\.|-)|medixiru|streamtape|mixdrop|filelions|lulustream)[^\s"'<>]*/gi,
        ) || [];
      for (const raw of matches)
        try {
          { const parsed=new URL(raw); if(isProviderUrl(parsed.href)&&!isForbiddenBridge(parsed.href)) providerRefs.add(parsed.href); }
        } catch {}
    });
    if (providerRefs.size) {
      chrome.runtime
        .sendMessage({
          type: "PROVIDERS_FOUND",
          urls: [...providerRefs],
          title: document.title,
        })
        .catch(() => {});
    }
    maybeShowAnalyze();
    report(items);
    if (state.deepScan && state.candidates.size)
      chrome.runtime
        .sendMessage({
          type: "PROBE_CANDIDATES",
          urls: [...state.candidates].slice(-20),
        })
        .catch(() => {});
  }
  function skipVideoAd(video) {
    if (!state.settings?.skipAds || allowed() || !video) return;
    const context = `${video.id} ${video.className} ${video.parentElement?.id || ""} ${video.parentElement?.className || ""} ${video.currentSrc || ""}`;
    const explicitAd =
      adSignal.test(context) ||
      document.querySelector(
        '[class*="ad-showing" i],[class*="video-ad" i],[id*="video-ad" i],[class*="preroll" i]',
      );
    if (!explicitAd) return;
    video.muted = true;
    reportBlocked();
    if (
      Number.isFinite(video.duration) &&
      video.duration > 0 &&
      video.duration <= 180
    )
      try {
        video.currentTime = Math.max(0, video.duration - 0.15);
      } catch {}
    document
      .querySelectorAll(
        '[class*="skip" i] button,button[class*="skip" i],[aria-label*="skip" i],[aria-label*="saltar" i]',
      )
      .forEach((button) => button.click());
  }
  function removeDetectedAds() {
    if (allowed()) return;
    document
      .querySelectorAll("[id],[class],[aria-label],[data-ad],[data-ad-slot]")
      .forEach((el) => {
        const tokens =
          `${el.id || ""} ${typeof el.className === "string" ? el.className : ""} ${el.getAttribute("aria-label") || ""}`
            .toLowerCase()
            .split(/[^a-z0-9]+/)
            .filter(Boolean);
        const marked =
          el.hasAttribute("data-ad") ||
          el.hasAttribute("data-ad-slot") ||
          tokens.some((token) =>
            /^(ad|ads|advert|advertisement|sponsor|sponsored|preroll|midroll|postroll|vast|vmap|popunder|interstitial)$/.test(
              token,
            ),
          );
        if (!marked || el.querySelector('video:not([class*="ad" i])')) return;
        const r = el.getBoundingClientRect();
        if (r.width > 40 && r.height > 20) {
          el.remove();
          reportBlocked();
        }
      });
  }
  function removeAnnoyances() {
    if (!state.settings?.removeOverlays || allowed()) return;
    document
      .querySelectorAll(
        '[class*="popup" i],[id*="popup" i],[class*="popunder" i],[id*="popunder" i],[class*="interstitial" i],[id*="interstitial" i]',
      )
      .forEach((el) => {
        if (
          !el.querySelector("video") &&
          el.getBoundingClientRect().width > 220
        ) {
          el.remove();
          reportBlocked();
        }
      });
    if (state.settings.aggressiveMode)
      document.querySelectorAll("body *").forEach((el) => {
        const s = getComputedStyle(el),
          r = el.getBoundingClientRect();
        if (
          (s.position === "fixed" || s.position === "sticky") &&
          Number(s.zIndex) > 999 &&
          r.width > innerWidth * 0.6 &&
          r.height > innerHeight * 0.5 &&
          !el.querySelector("video")
        )
          el.remove();
      });
    document.documentElement.style.overflow = "";
    if (document.body) document.body.style.overflow = "";
  }
  document.addEventListener(
    "click",
    (event) => {
      if (!state.active) return;
      if (!state.settings?.enabled || !state.settings.blockPopups || allowed())
        return;
      const link = event.target.closest?.("a[href]");
      if (!link) return;
      let target;
      try {
        target = new URL(link.href, location.href);
      } catch {
        return;
      }
      if (
        target.hostname !== location.hostname &&
        suspicious.test(`${target.hostname}${target.pathname}`) &&
        !/\.(mp4|webm|m3u8)(?:[?#]|$)/i.test(target.href)
      ) {
        event.preventDefault();
        event.stopImmediatePropagation();
        reportBlocked();
      }
    },
    true,
  );
  Promise.all([
    settings(),
    chrome.runtime
      .sendMessage({ type: "GET_SCAN_MODE" })
      .catch(() => ({ deepScan: false })),
  ]).then(([, mode]) => {
    state.deepScan = Boolean(mode?.deepScan);
    if (!state.settings.enabled || allowed()) return;
    let started = false;
    const movieSignal = (root = document) => {
      const scope = root?.querySelector ? root : document;
      if (isProviderUrl(location.href) && !isForbiddenBridge(location.href)) return true;
      if (
        scope.querySelector?.(
          'iframe[src*="player" i],iframe[src*="embed" i],a[href*="streamwish" i],a[href*="filemoon" i],a[href*="vidhide" i],a[href*="voesx" i],a[href*="voe." i],a[href*="voe-" i],a[href*="doodstream" i],a[href*="dood." i],a[href*="dood-" i],a[href*="medixiru" i],a[href*="streamtape" i],a[href*="mixdrop" i],a[href*="filelions" i],a[href*="lulustream" i]',
        )
      )
        return true;
      const moviePath =
        /(?:pelicula|movie|film|serie|season|temporada|episode|episodio|watch|ver)[-_\/]/i.test(
          location.pathname,
        );
      if (!moviePath) return false;
      return Boolean(
        scope.querySelector?.(
          'video,iframe[src],embed[src],object[data],a[href*="player" i],a[href*="embed" i]',
        ),
      );
    };
    startFull = () => {
      if (started) return;
      started = true;
      state.active = true;
      chrome.runtime.sendMessage({ type: "INJECT_INTERFACE_STYLES" }).catch(() => {});
      const observer = new MutationObserver((records) => {
        for (const record of records)
          for (const node of record.addedNodes)
            if (node.nodeType === 1) scan(node);
        removeAnnoyances();
        removeDetectedAds();
      });
      if (!protectedMode) maybeShowResume();
      scan();
      removeAnnoyances();
      removeDetectedAds();
      document.addEventListener(
        "playing",
        (event) => {
          if (event.target instanceof HTMLVideoElement) skipVideoAd(event.target);
        },
        true,
      );
      observer.observe(document.documentElement, { childList: true, subtree: true });
      setInterval(scan, 3000);
      setInterval(() => {
        if (location.href !== state.pageUrl) {
          state.pageUrl = location.href;
          state.dismissedUrl = null;
          state.found.clear();
          state.candidates.clear();
          providerRefs.clear();
          removeAnalyzeSurface();
          setTimeout(() => scan(document), 500);
        }
      }, 1000);
    };
    const begin = () => {
      if (state.active || movieSignal()) {
        startFull();
        return;
      }
      let passiveTimer = 0;
      const passiveObserver = new MutationObserver((records) => {
        if (!records.some((record) => record.addedNodes.length)) return;
        clearTimeout(passiveTimer);
        passiveTimer = setTimeout(() => {
          if (!movieSignal(document)) return;
          passiveObserver.disconnect();
          startFull();
        }, 250);
      });
      passiveObserver.observe(document.documentElement, { childList: true, subtree: true });
      setTimeout(() => passiveObserver.disconnect(), 45000);
    };
    document.documentElement
      ? begin()
      : document.addEventListener("DOMContentLoaded", begin, { once: true });
  });
  chrome.runtime.onMessage.addListener((message) => {
    if (message.type === "SAFE_SCAN_START") {
      state.active = true;
      startFull();
      runSafeScan();
    }
    if (message.type === "ENABLE_PROTECTED_MODE" && !protectedMode) {
      state.active = true;
      protectedMode = true;
      removeAnalyzeSurface();
      startFull();
      if (isProviderUrl(location.href) && !isForbiddenBridge(location.href)) {
        providerRefs.add(location.href);
        chrome.runtime
          .sendMessage({
            type: "PROVIDERS_FOUND",
            urls: [...providerRefs],
            title: document.title,
          })
          .catch(() => {});
      }
      setTimeout(runSafeScan, 700);
    }
    if (message.type === "PAUSE_ORIGINAL")
      document.querySelectorAll("video").forEach((video) => video.pause());
  });
})();
