// El Eje page-context probe. Injected by content.js into YouTube's MAIN world to read the
// page's embedded data — ytInitialPlayerResponse / ytInitialData, the SAME source yt-dlp
// reads — and postMessage the video's title, channel, FULL description and any "Music in
// this video" detection back to the (isolated-world) content script. This is bulletproof
// where scraping the rendered description DOM is not: the description is often collapsed or
// lazily rendered, but videoDetails.shortDescription is always present and current.
(function () {
  function playerResponse() {
    try {
      if (window.ytInitialPlayerResponse) return window.ytInitialPlayerResponse;
      const a = window.ytplayer && window.ytplayer.config && window.ytplayer.config.args;
      if (a && a.player_response) return JSON.parse(a.player_response);
    } catch (e) { /* ignore */ }
    return null;
  }

  // YouTube's own detected song — walk ytInitialData for the "Music in this video" section
  // and pull its Song / Artist info rows → {song, artist}.
  function detectedMusic(rootData) {
    let found = null;
    const seen = new Set();
    (function walk(n, depth) {
      if (found || !n || depth > 14 || typeof n !== "object" || seen.has(n)) return;
      seen.add(n);
      const sec = n.videoDescriptionMusicSectionRenderer || n.musicSectionRenderer;
      if (sec) {
        const rows = [];
        (function collect(x, d) {
          if (!x || d > 8 || typeof x !== "object") return;
          if (x.infoRowRenderer) rows.push(x.infoRowRenderer);
          for (const k in x) collect(x[k], d + 1);
        })(sec, 0);
        const out = {};
        const str = t => t && (t.simpleText || (t.runs && t.runs.map(r => r.text).join("")));
        for (const r of rows) {
          const label = (str(r.title) || "").toLowerCase();
          const val = str(r.defaultMetadata) || str(r.expandedMetadata) || "";
          if (!val) continue;
          if (!out.song && /song|canci|t[ií]tulo|brano|lied/.test(label)) out.song = val;
          else if (!out.artist && /artist|m[uú]sic|interpret/.test(label)) out.artist = val;
          else if (!out.album && /album|álbum|disco/.test(label)) out.album = val;
        }
        if (out.song) { found = out; return; }
      }
      if (Array.isArray(n)) { for (const it of n) walk(it, depth + 1); }
      else for (const k in n) walk(n[k], depth + 1);
    })(rootData, 0);
    return found;
  }

  function gather() {
    const pr = playerResponse() || {};
    const vd = pr.videoDetails || {};
    let music = null;
    try { music = detectedMusic(window.ytInitialData); } catch (e) { /* ignore */ }
    return {
      __elejeYT: 1,
      title: vd.title || "",
      author: vd.author || "",
      description: vd.shortDescription || "",
      music,
    };
  }

  function post() { try { window.postMessage(gather(), location.origin); } catch (e) { /* ignore */ } }
  post();
  // YouTube is an SPA — navigations swap the data without a reload. Re-post on each so the
  // content script always has the CURRENT video's metadata.
  for (const ev of ["yt-navigate-finish", "yt-page-data-updated", "yt-player-updated"]) {
    window.addEventListener(ev, () => setTimeout(post, 400));
  }
})();
