// Content script: injects an "An NextJobs senden" button next to the
// Indeed job description, scrapes the job details and forwards them to the
// tracker's import API (via the background service worker).

(function () {
  'use strict';

  const BTN_ID = 'bt-import-container';

  // ----- Scraping ---------------------------------------------------------

  function cleanText(el) {
    if (!el) return '';
    return (el.innerText || el.textContent || '').replace(/\s+\n/g, '\n').trim();
  }

  // The visible detail pane (right side on search pages, whole page on /viewjob).
  function getDetailRoot() {
    return (
      document.querySelector('.jobsearch-JobComponent') ||
      document.querySelector('#jobsearch-ViewjobPaneWrapper') ||
      document.querySelector('.jobsearch-RightPane') ||
      document
    );
  }

  function getTitle(root) {
    const el =
      root.querySelector('[data-testid="jobsearch-JobInfoHeader-title"]') ||
      root.querySelector('.jobsearch-JobInfoHeader-title');
    if (!el) return '';
    // Drop the trailing "- job post" / "- Stellenanzeige" label Indeed appends.
    let text = cleanText(el);
    text = text.replace(/\s*-\s*(job post|Stellenanzeige)\s*$/i, '').trim();
    return text;
  }

  function getCompany(root) {
    const container =
      root.querySelector('[data-testid="jobsearch-CompanyInfoContainer"]') || root;
    const el =
      container.querySelector('[data-testid="inlineHeader-companyName"]') ||
      container.querySelector('[data-company-name="true"]') ||
      container.querySelector('[data-testid="company-name"]');
    return cleanText(el);
  }

  function getLocation(root) {
    const el =
      root.querySelector('[data-testid="jobsearch-JobInfoHeader-companyLocation"]') ||
      root.querySelector('[data-testid="inlineHeader-companyLocation"]');
    return cleanText(el);
  }

  function getSalary(root) {
    const el =
      root.querySelector('#salaryInfoAndJobType') ||
      root.querySelector('[data-testid="jobsearch-OtherJobDetailsContainer"]');
    return cleanText(el);
  }

  function getDescription(root) {
    const el = root.querySelector('#jobDescriptionText');
    return cleanText(el);
  }

  // Build a stable job URL. On the search page the selected job key lives in the
  // `vjk` query param; a clean /viewjob URL is nicer than the search URL.
  function getSourceUrl() {
    try {
      const u = new URL(window.location.href);
      const vjk = u.searchParams.get('vjk') || u.searchParams.get('jk');
      if (vjk) return `${u.origin}/viewjob?jk=${vjk}`;
    } catch (_) { /* ignore */ }
    return window.location.href;
  }

  function scrapeJob() {
    const root = getDetailRoot();
    return {
      firma: getCompany(root),
      stelle: getTitle(root),
      ort: getLocation(root),
      gehalt: getSalary(root),
      stellenbeschreibung: getDescription(root),
      quelle_url: getSourceUrl(),
      art: 'Indeed',
    };
  }

  // ----- Button UI --------------------------------------------------------

  const ICON_SEND =
    '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" ' +
    'stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13">' +
    '</line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>';

  function buildContainer() {
    const wrap = document.createElement('div');
    wrap.className = 'bt-import-wrap';
    wrap.id = BTN_ID;

    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'bt-import-btn';
    btn.innerHTML = ICON_SEND + '<span>An NextJobs senden</span>';

    const status = document.createElement('div');
    status.className = 'bt-import-status';

    btn.addEventListener('click', () => onClick(btn, status));

    wrap.appendChild(btn);
    wrap.appendChild(status);
    return wrap;
  }

  function setStatus(status, html, cls) {
    status.className = 'bt-import-status' + (cls ? ' ' + cls : '');
    status.innerHTML = html;
  }

  function duplicateWarning(matches) {
    const lines = (matches || []).slice(0, 5).map(function (m) {
      const parts = [m.firma, m.stelle].filter(Boolean).join(' — ');
      const meta = [m.datum, m.status].filter(Boolean).join(', ');
      return '• ' + parts + (meta ? ' (' + meta + ')' : '');
    });
    return 'Für diese Stelle scheint bereits eine Bewerbung zu existieren:\n\n' +
      lines.join('\n') + '\n\nTrotzdem als weitere Bewerbung importieren?';
  }

  function onClick(btn, status) {
    const job = scrapeJob();

    if (!job.firma || !job.stelle) {
      setStatus(status, 'Konnte Firma oder Stelle nicht auslesen. Bitte eine Stelle öffnen.', 'bt-err');
      return;
    }

    const label = btn.querySelector('span');
    const originalLabel = label ? label.textContent : '';

    const send = (payload) => {
      btn.disabled = true;
      btn.innerHTML = '<span class="bt-spin"></span><span>Wird gesendet…</span>';
      setStatus(status, '', '');

      chrome.runtime.sendMessage({ type: 'IMPORT_JOB', payload: payload }, (resp) => {
        btn.innerHTML = ICON_SEND + '<span>' + (originalLabel || 'An NextJobs senden') + '</span>';

        if (chrome.runtime.lastError) {
          btn.disabled = false;
          setStatus(status, 'Fehler: ' + chrome.runtime.lastError.message, 'bt-err');
          return;
        }
        if (resp && resp.duplicate) {
          btn.disabled = false;
          if (confirm(duplicateWarning(resp.matches))) {
            send(Object.assign({}, payload, { force: true }));
          } else {
            setStatus(status, 'Import abgebrochen (mögliches Duplikat).', '');
          }
          return;
        }
        if (!resp || !resp.ok) {
          btn.disabled = false;
          setStatus(status, (resp && resp.error) || 'Unbekannter Fehler.', 'bt-err');
          return;
        }

        const link = resp.openUrl
          ? ` <a href="${resp.openUrl}" target="_blank" rel="noopener">Entwurf öffnen</a>`
          : '';
        setStatus(
          status,
          '✓ ' + (resp.message || 'Als Entwurf angelegt. Unterlagen werden erstellt.') + link,
          'bt-ok'
        );
        setTimeout(() => { btn.disabled = false; }, 1500);
      });
    };

    send(job);
  }

  // ----- Injection + SPA handling -----------------------------------------

  // Insert the button just above the job description text, so it sits right
  // next to the "Vollständige Stellenbeschreibung" heading.
  function findAnchor() {
    const heading = document.querySelector('#jobDescriptionTitleHeading');
    if (heading) return { node: heading, position: 'after' };
    const desc = document.querySelector('#jobDescriptionText');
    if (desc) return { node: desc, position: 'before' };
    const titleContainer = document.querySelector('.jobsearch-JobInfoHeader-title-container');
    if (titleContainer) return { node: titleContainer, position: 'after' };
    return null;
  }

  function inject() {
    const anchor = findAnchor();
    if (!anchor) return;

    const existing = document.getElementById(BTN_ID);
    // Re-inject if missing or detached from the current anchor's parent.
    if (existing && existing.parentNode === anchor.node.parentNode) return;
    if (existing) existing.remove();

    const container = buildContainer();
    if (anchor.position === 'after') {
      anchor.node.parentNode.insertBefore(container, anchor.node.nextSibling);
    } else {
      anchor.node.parentNode.insertBefore(container, anchor.node);
    }
  }

  // Indeed is a single-page app: the detail pane swaps without a full reload.
  // Observe DOM changes and (debounced) re-inject / keep the button in place.
  let debounce = null;
  const observer = new MutationObserver(() => {
    if (debounce) clearTimeout(debounce);
    debounce = setTimeout(inject, 300);
  });

  function start() {
    inject();
    observer.observe(document.body, { childList: true, subtree: true });
  }

  if (document.body) {
    start();
  } else {
    document.addEventListener('DOMContentLoaded', start);
  }
})();
