function normalizeUrl(url) {
  try {
    const parsed = new URL(url, window.location.href);

    if (parsed.hostname.includes('youtube.com') || parsed.hostname === 'youtu.be') {
      const videoId = parsed.searchParams.get('v') || (parsed.hostname === 'youtu.be' ? parsed.pathname.replace('/', '') : '');
      if (videoId) {
        return `https://www.youtube.com/watch?v=${videoId}`;
      }
    }

    parsed.hash = '';
    ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'feature', 'si'].forEach((key) => {
      parsed.searchParams.delete(key);
    });
    return parsed.toString();
  } catch (_error) {
    return url;
  }
}

function absoluteUrl(value) {
  if (!value) {
    return null;
  }

  try {
    return new URL(value, window.location.href).toString();
  } catch (_error) {
    return null;
  }
}

function collectMediaCandidates() {
  const candidates = new Map();

  const addCandidate = (url, title, kind) => {
    const absolute = absoluteUrl(url);
    if (!absolute || !(absolute.startsWith('https://') || absolute.startsWith('http://'))) {
      return;
    }

    const canonicalUrl = normalizeUrl(absolute);
    const key = `${kind}:${canonicalUrl}`;
    if (candidates.has(key)) {
      return;
    }

    candidates.set(key, {
      url: absolute,
      canonicalUrl,
      title: title || document.title || canonicalUrl,
      kind,
      domain: new URL(absolute).hostname
    });
  };

  document.querySelectorAll('video, audio').forEach((element) => {
    addCandidate(element.currentSrc || element.src, element.getAttribute('title') || document.title, element.tagName.toLowerCase());
    element.querySelectorAll('source').forEach((source) => {
      addCandidate(source.src, element.getAttribute('title') || document.title, element.tagName.toLowerCase());
    });
  });

  document.querySelectorAll('a[href]').forEach((anchor) => {
    const href = anchor.href;
    const title = anchor.textContent?.trim() || anchor.getAttribute('title') || document.title;
    if (/\.(mp3|m4a|wav|aac|mp4|mov|mkv)(\?.*)?$/i.test(href)) {
      addCandidate(href, title, 'download');
      return;
    }

    if (/youtube\.com|youtu\.be|spotify\.com|soundcloud\.com|vimeo\.com|loom\.com|podcasts?/i.test(href)) {
      addCandidate(href, title, 'link');
    }
  });

  const canonicalHref = document.querySelector('link[rel="canonical"]')?.href;
  const ogUrl = document.querySelector('meta[property="og:url"]')?.content;
  const pageUrl = normalizeUrl(canonicalHref || ogUrl || window.location.href);

  addCandidate(pageUrl, document.title, 'page');

  return Array.from(candidates.values()).sort((left, right) => {
    const priority = { video: 0, audio: 1, download: 2, link: 3, page: 4 };
    return (priority[left.kind] ?? 99) - (priority[right.kind] ?? 99);
  });
}

chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
  if (message?.type === 'quickwhisper:getPageContext') {
    const canonicalHref = document.querySelector('link[rel="canonical"]')?.href;
    const ogUrl = document.querySelector('meta[property="og:url"]')?.content;
    const pageUrl = normalizeUrl(canonicalHref || ogUrl || window.location.href);
    const selectedText = window.getSelection()?.toString()?.trim() || '';
    const media = collectMediaCandidates();

    sendResponse({
      title: document.title,
      pageUrl: window.location.href,
      canonicalUrl: pageUrl,
      domain: window.location.hostname,
      selectedText,
      media
    });
    return true;
  }

  return false;
});
