// content/hunter-form-filler.js
// ════════════════════════════════════════════════════════════════════
// Hunter — Contact Form Filler
// Injected on prospect sites when the user (or auto-pipeline) opens them
// to submit a contact form. Detects common patterns (name/email/phone/
// message + textarea), fills them, and submits — all without needing the
// site's email to be publicly listed.
//
// Public API (called via chrome.tabs.sendMessage from background SW):
//   FILL_CONTACT_FORM { name, email, phone, message, company? }
//     → { ok, filled: { name, email, phone, message }, submitted, formUrl, error? }
//   DETECT_CONTACT_FORM
//     → { ok, found: bool, formScore, fields: { name, email, phone, message }, formUrl }
// ════════════════════════════════════════════════════════════════════

const NAME_HINTS    = ['name', 'שם', 'fullname', 'full_name', 'full-name', 'first', 'last'];
const EMAIL_HINTS   = ['email', 'mail', 'אימייל', 'דואל', 'דוא"ל', 'דוא״ל', 'דוא"ל', 'e-mail'];
const PHONE_HINTS   = ['phone', 'tel', 'mobile', 'טלפון', 'נייד', 'cell'];
const MESSAGE_HINTS = ['message', 'msg', 'body', 'comment', 'comments', 'enquiry', 'inquiry',
                       'question', 'הודעה', 'תוכן', 'פנייה', 'תוכן ההודעה', 'תיאור', 'שאלה'];
const COMPANY_HINTS = ['company', 'org', 'organization', 'business', 'חברה', 'עסק', 'ארגון'];
const SUBJECT_HINTS = ['subject', 'topic', 'נושא'];

// ─── Score a field by name/id/placeholder/label match ───────────────
function fieldScore(el, hints) {
  const candidates = [
    el.name || '', el.id || '', el.placeholder || '',
    el.getAttribute('aria-label') || '', el.getAttribute('title') || '',
  ];
  // Also check associated <label>
  if (el.id) {
    const lab = document.querySelector(`label[for="${CSS.escape(el.id)}"]`);
    if (lab) candidates.push(lab.textContent || '');
  }
  // Parent label (label wrapping input)
  const parentLab = el.closest('label');
  if (parentLab) candidates.push(parentLab.textContent || '');
  const haystack = candidates.join(' ').toLowerCase();
  let score = 0;
  for (const h of hints) if (haystack.includes(h.toLowerCase())) score++;
  return score;
}

// ─── Find the best contact form on the current page ─────────────────
function findContactForm() {
  const forms = Array.from(document.querySelectorAll('form'));
  if (!forms.length) return null;
  let best = null, bestScore = 0;
  for (const form of forms) {
    let s = 0;
    const action = (form.action || '').toLowerCase();
    if (action.includes('contact') || action.includes('lead') || action.includes('inquiry')) s += 3;
    if ((form.id || '').toLowerCase().includes('contact')) s += 2;
    if ((form.className || '').toLowerCase().includes('contact')) s += 2;
    // Bonus for having a textarea (real messages are long)
    if (form.querySelector('textarea')) s += 2;
    // Bonus for having email + name fields
    const inputs = form.querySelectorAll('input, textarea');
    let hasEmail = false, hasName = false;
    for (const inp of inputs) {
      if (fieldScore(inp, EMAIL_HINTS) > 0) hasEmail = true;
      if (fieldScore(inp, NAME_HINTS) > 0) hasName = true;
    }
    if (hasEmail) s += 3;
    if (hasName) s += 1;
    // Penalty for search/login forms
    if (action.includes('search') || action.includes('login') || action.includes('signin')) s -= 5;
    if ((form.id || '').toLowerCase().match(/login|search|signin/)) s -= 5;
    if (s > bestScore) { bestScore = s; best = form; }
  }
  return best && bestScore >= 3 ? { form: best, score: bestScore } : null;
}

// ─── Map fields in a form to logical roles ──────────────────────────
function mapFields(form) {
  const inputs = Array.from(form.querySelectorAll('input, textarea, select'));
  const map = { name: null, email: null, phone: null, message: null, company: null, subject: null };
  const fieldsByHints = [
    ['message', MESSAGE_HINTS],
    ['email', EMAIL_HINTS],
    ['name', NAME_HINTS],
    ['phone', PHONE_HINTS],
    ['company', COMPANY_HINTS],
    ['subject', SUBJECT_HINTS],
  ];
  // First pass: explicit type matches
  for (const inp of inputs) {
    if (inp.type === 'email' && !map.email) map.email = inp;
    else if (inp.type === 'tel' && !map.phone) map.phone = inp;
    else if (inp.tagName === 'TEXTAREA' && !map.message) map.message = inp;
  }
  // Second pass: score by hints
  for (const [key, hints] of fieldsByHints) {
    if (map[key]) continue;
    let best = null, bestScore = 0;
    for (const inp of inputs) {
      if (Object.values(map).includes(inp)) continue;
      const s = fieldScore(inp, hints);
      if (s > bestScore) { bestScore = s; best = inp; }
    }
    if (bestScore > 0) map[key] = best;
  }
  return map;
}

// ─── Fill a field with proper React/Vue-compatible event firing ─────
function setValue(input, value) {
  if (!input) return false;
  const proto = input instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
  const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
  if (setter) setter.call(input, value);
  else input.value = value;
  // React listens to these events
  input.dispatchEvent(new Event('input', { bubbles: true }));
  input.dispatchEvent(new Event('change', { bubbles: true }));
  input.dispatchEvent(new Event('blur', { bubbles: true }));
  return true;
}

// ─── Detect — public API ────────────────────────────────────────────
function detectContactForm() {
  const found = findContactForm();
  if (!found) return { ok: true, found: false };
  const map = mapFields(found.form);
  return {
    ok: true, found: true, formScore: found.score,
    formUrl: location.href,
    fields: {
      name: !!map.name, email: !!map.email, phone: !!map.phone,
      message: !!map.message, company: !!map.company, subject: !!map.subject,
    },
  };
}

// ─── Fill — public API ──────────────────────────────────────────────
async function fillContactForm({ name, email, phone, message, company, subject, autoSubmit = false }) {
  const found = findContactForm();
  if (!found) return { ok: false, error: 'no contact form found on page' };
  const map = mapFields(found.form);
  const filled = { name: false, email: false, phone: false, message: false, company: false, subject: false };
  if (name && map.name) filled.name = setValue(map.name, name);
  if (email && map.email) filled.email = setValue(map.email, email);
  if (phone && map.phone) filled.phone = setValue(map.phone, phone);
  if (message && map.message) filled.message = setValue(map.message, message);
  if (company && map.company) filled.company = setValue(map.company, company);
  if (subject && map.subject) filled.subject = setValue(map.subject, subject);

  let submitted = false;
  if (autoSubmit && filled.email && filled.message) {
    // Find a submit button (prefer one inside the form)
    const submitBtn = found.form.querySelector('button[type="submit"], input[type="submit"]')
                   || found.form.querySelector('button:not([type="button"])')
                   || found.form.querySelector('[role="button"]');
    if (submitBtn) {
      try { submitBtn.click(); submitted = true; } catch {}
    }
    // Or try form.requestSubmit()
    if (!submitted && typeof found.form.requestSubmit === 'function') {
      try { found.form.requestSubmit(); submitted = true; } catch {}
    }
  }

  return {
    ok: true, formUrl: location.href, formScore: found.score,
    filled, submitted,
  };
}

// ─── Message handler ────────────────────────────────────────────────
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
  (async () => {
    try {
      if (msg.type === 'DETECT_CONTACT_FORM') return sendResponse(detectContactForm());
      if (msg.type === 'FILL_CONTACT_FORM') return sendResponse(await fillContactForm(msg.payload || {}));
      sendResponse({ ok: false, error: 'unknown message type' });
    } catch (e) { sendResponse({ ok: false, error: String(e?.message || e) }); }
  })();
  return true;
});

console.log('[organicai-form-filler] loaded on', location.host);
