// Plain script. Two roles:
//   - Loaded as the first entry in each content_scripts.js array. Chrome
//     concatenates the array into one isolated-world script, so the
//     downstream content script can read MaxyLinkedinExtractors directly.
//   - Loaded into jsdom by the tests, which evaluate this file in a
//     wrapped function scope so the same globalThis assignment exposes the
//     functions to the test runtime.
//
// No imports, no exports — the manifest-v3 content script context does not
// support ES module imports, and the bundler-free deploy path is the point.

;(function () {
  function sel(doc, primary, fallback) {
    return doc.querySelector(primary) || doc.querySelector(fallback)
  }

  function txt(el) {
    return el ? el.textContent.trim().replace(/\s+/g, ' ') : ''
  }

  function allTxt(el) {
    if (!el) return ''
    return el.textContent
      .replace(/\r/g, '')
      .replace(/[ \t]+/g, ' ')
      .replace(/\n{3,}/g, '\n\n')
      .trim()
  }

  function extractProfile(doc) {
    const name = txt(sel(doc, 'h1.text-heading-xlarge', 'section.top-card-layout h1'))
    const headline = txt(sel(doc, '[data-test-headline]', '.text-body-medium.break-words'))
    const location = txt(sel(doc, '[data-test-location]', '.text-body-small.inline.t-black--light'))
    const currentTitle = txt(sel(
      doc,
      '[data-test-current-position] .position-title',
      'section#experience li:first-child .t-bold > span:first-child',
    ))
    const currentCompany = txt(sel(
      doc,
      '[data-test-current-position] .position-company',
      'section#experience li:first-child .t-normal > span:first-child',
    ))
    const bodyEl = sel(doc, 'main', 'body')
    const bodyText = allTxt(bodyEl)

    const missing = []
    if (!name) missing.push('name')
    if (!headline) missing.push('headline')
    if (!bodyText) missing.push('bodyText')
    if (missing.length) return { ok: false, missing: missing }

    return {
      ok: true,
      payload: {
        name: name,
        headline: headline,
        location: location || '',
        currentTitle: currentTitle || null,
        currentCompany: currentCompany || null,
        bodyText: bodyText,
      },
    }
  }

  function extractThread(doc) {
    const root =
      doc.querySelector('.msg-thread') ||
      doc.querySelector('[data-test-thread-root]')
    if (!root) return { ok: false, missing: ['threadRoot'] }

    const events = root.querySelectorAll('.msg-s-message-list__event, [data-test-message-item]')
    if (!events.length) return { ok: false, missing: ['messages'] }

    const participantsMap = new Map()
    const lines = []

    events.forEach(function (ev) {
      const nameEl =
        ev.querySelector('.msg-s-event-listitem__name') ||
        ev.querySelector('[data-test-sender-name]')
      const linkEl =
        ev.querySelector('a.msg-s-event-listitem__link[href*="/in/"]') ||
        ev.querySelector('[data-test-sender-link]')
      const timeEl =
        ev.querySelector('time.msg-s-event-listitem__timestamp[datetime]') ||
        ev.querySelector('[data-test-message-time][datetime]')
      const bodyEl =
        ev.querySelector('.msg-s-event-listitem__body') ||
        ev.querySelector('[data-test-message-body]')

      const name = txt(nameEl)
      const body = allTxt(bodyEl)
      if (!name || !body) return

      const href = linkEl && linkEl.getAttribute('href')
      const profileUrl = href
        ? href.startsWith('http')
          ? href
          : 'https://www.linkedin.com' + href
        : null
      if (!participantsMap.has(name)) participantsMap.set(name, profileUrl)

      const datetime = timeEl && timeEl.getAttribute('datetime')
      lines.push(name + (datetime ? ' [' + datetime + ']' : '') + ': ' + body)
    })

    if (!lines.length) return { ok: false, missing: ['messages'] }

    const participants = Array.from(participantsMap.entries()).map(function (entry) {
      return { name: entry[0], profileUrl: entry[1] }
    })

    return {
      ok: true,
      payload: {
        participants: participants,
        bodyText: lines.join('\n'),
      },
    }
  }

  globalThis.MaxyLinkedinExtractors = {
    extractProfile: extractProfile,
    extractThread: extractThread,
  }
})()
