const apify = require('./apify');

function normSet(items) {
  return new Set((items || []).map(s => (s || '').toLowerCase().trim()).filter(Boolean));
}

function quickScore(candidate, applicantAttrs) {
  let score = 0;
  const cs = normSet(candidate.schools), cc = normSet(candidate.companies);
  const ci = normSet(candidate.industries), cl = normSet(candidate.languages);
  const loc = (candidate.location || '').toLowerCase();
  const as = normSet(applicantAttrs.schools), ac = normSet(applicantAttrs.companies);
  const ai = normSet(applicantAttrs.industries), al = normSet(applicantAttrs.languages);
  const aloc = normSet(applicantAttrs.locations); 
  if (candidate.is_direct_connection) score += 100;
  if ([...cs].some(v => as.has(v)) && [...cc].some(v => ac.has(v))) score += 25;
  if ([...cc].filter(v => ac.has(v) && v !== 'google').length) score += 20;
  if ([...cs].some(v => as.has(v))) score += 15;
  if ([...aloc].some(v => loc.includes(v))) score += 10;
  if ([...ci].some(v => ai.has(v))) score += 8;
  if ([...cl].filter(v => al.has(v) && v !== 'english').length) score += 5;
  return score;
}

function dedupe(rows) {
  const seen = new Set();
  return rows.filter(r => {
    const url = (r.linkedin_url || '').toLowerCase();
    if (url && seen.has(url)) return false;
    if (url) seen.add(url);
    return true;
  });
}

async function runConcentricSearch({ applicantAttrs, targetCompany, targetCompanyLinkedin, csvConnections, cb }) {
  const settings = {
    earlyExit: parseInt(process.env.EARLY_EXIT_MATCH_COUNT || 5),
    maxPages: parseInt(process.env.MAX_EMPLOYEE_PAGES || 1),
    topToEnrich: parseInt(process.env.TOP_CANDIDATES_TO_ENRICH || 8),
  };
  const stats = { profiles_analyzed: 0, direct_connections_found: 0 };

  // Ring 0: CSV
  if (cb) cb('checking_csv_connections');
  const { findDirectConnections } = require('./csv');
  const direct = findDirectConnections(csvConnections || [], targetCompany);
  stats.direct_connections_found = direct.length;
  const ring0 = direct.map(d => ({
    linkedin_url: d.linkedin_url || '', name: d.name || '', title: d.position || '',
    company: d.company || '', location: null, schools: [], companies: [d.company || ''],
    is_direct_connection: true,
  }));

  if (ring0.length >= settings.earlyExit) {
    stats.profiles_analyzed = ring0.length;
    return { candidates: ring0, stats };
  }

  // Rings 1-4: company employees
  if (cb) cb('scraping_company');
  let allEmployees = [];
  for (let page = 1; page <= settings.maxPages; page++) {
    try {
      const emp = await apify.searchCompanyEmployees(targetCompany, targetCompanyLinkedin, page);
      allEmployees = allEmployees.concat(emp);
    } catch (e) {
      console.error('[concentric] searchCompanyEmployees failed (page', page, '):', e.message);
    }
  }
  stats.profiles_analyzed = allEmployees.length + ring0.length;

  const directUrls = new Set(ring0.map(c => (c.linkedin_url || '').toLowerCase()).filter(Boolean));
  for (const e of allEmployees) {
    if (directUrls.has((e.linkedin_url || '').toLowerCase())) e.is_direct_connection = true;
  }

  const merged = dedupe([...ring0, ...allEmployees]);
  for (const c of merged) c._quick_score = quickScore(c, applicantAttrs);
  merged.sort((a, b) => b._quick_score - a._quick_score);

  const top = merged.slice(0, settings.topToEnrich);
  if (cb) cb('enriching_top_candidates');
  for (const c of top) {
    if (c.is_direct_connection || !c.linkedin_url) continue;
    try {
      const enriched = await apify.enrichProfile(c.linkedin_url);
      for (const [k, v] of Object.entries(enriched)) {
        if (v && !c[k]) c[k] = v;
      }
    } catch {}
  }

  return { candidates: top, stats };
}

module.exports = { runConcentricSearch };
