const axios = require('axios');
const db = require('./db');

const MOCK_MODE = () => process.env.MOCK_MODE !== 'false' && process.env.MOCK_MODE !== '0';
const APIFY_BASE = 'https://api.apify.com/v2';
const ACTOR_PROFILE = 'supreme_coder~linkedin-profile-scraper';
const ACTOR_EMPLOYEES = 'harvestapi~linkedin-company-employees';

const MOCK_PROFILE = {
  linkedin_url: '',
  fullName: 'Jane Doe',
  headline: 'Founder & CEO at Hippo.Build | YC W23 | LatAm Fintech SaaS',
  locationName: 'San Francisco, CA',
  schools: [{ schoolName: 'DTU' }],
  companies: [{ companyName: 'Hippo.Build' }, { companyName: 'YC' }],
  industries: [{ name: 'FinTech' }, { name: 'SaaS' }],
  languages: [{ name: 'English' }, { name: 'Portuguese' }],
  skills: ['Product Management', 'Fintech', 'B2B SaaS'],
};

const MOCK_EMPLOYEES = [
  { fullName: 'Adrian Chan', headline: 'Head of Channel Partners', publicProfileUrl: 'https://linkedin.com/in/adrianchan', locationName: 'San Francisco', schools: [], companies: [{ companyName: 'Google' }], industries: [], languages: [] },
  { fullName: 'David Park', headline: 'AI GTM Lead', publicProfileUrl: 'https://linkedin.com/in/davidpark', locationName: 'New York', schools: [{ schoolName: 'DTU' }], companies: [{ companyName: 'Google' }], industries: [], languages: [] },
];

const MOCK_MATCHES = [
  { rank: 1, name: 'Adrian Chan', title: 'Head of Channel Partners', linkedin_url: 'https://linkedin.com/in/adrianchan', location: 'San Francisco', score: 82, connection_type: 'strong_match', match_reasons: [{ type: 'location', detail: 'Both in San Francisco' }], approach_angle: 'Shared city and GTM focus.', draft_message: 'Hi Adrian — YC founder (LatAm fintech SaaS) targeting Google. You lead channel partners for SMBs — the exact GTM layer I\'m trying to learn. Any advice?' },
  { rank: 2, name: 'David Park', title: 'AI GTM Lead', linkedin_url: 'https://linkedin.com/in/davidpark', location: 'New York', score: 75, connection_type: 'strong_match', match_reasons: [{ type: 'school', detail: 'Both attended DTU' }], approach_angle: 'Same school, founder-to-big-tech path.', draft_message: 'Hi David — ex-co-founder, AI/ML PM background, YC/LatAm SaaS. You lead AI GTM at Google — same founder-to-big-tech path I\'m on. Worth 15 min?' },
];

function normalizeUrl(url) { return (url || '').trim().toLowerCase().replace(/\/$/, ''); }

function first(obj, ...keys) {
  for (const k of keys) { const v = obj[k]; if (v !== undefined && v !== null && v !== '' && !(Array.isArray(v) && !v.length)) return v; }
  return null;
}

function extractNames(items, ...keys) {
  return (items || []).flatMap(it => {
    if (typeof it === 'string' && it.trim()) return [it.trim()];
    if (typeof it === 'object' && it) {
      for (const k of keys) { if (it[k] && typeof it[k] === 'string') return [it[k].trim()]; }
    }
    return [];
  });
}

function normalizeEmployee(raw) {
  const linkedin_url = first(raw, 'publicProfileUrl', 'profileUrl', 'linkedinUrl', 'url') || '';
  const name = first(raw, 'fullName', 'name', 'displayName') || `${raw.firstName || ''} ${raw.lastName || ''}`.trim();
  const title = first(raw, 'headline', 'title', 'position', 'jobTitle') || '';
  let location = first(raw, 'locationName', 'location', 'geoLocation') || '';
  if (typeof location === 'object' && location) location = location.name || location.city || '';
  const schoolsRaw = first(raw, 'schools', 'education') || [];
  const companiesRaw = first(raw, 'companies', 'experience', 'positions') || [];
  const industriesRaw = (typeof raw.industries === 'string') ? [raw.industries] : (raw.industries || []);
  const languagesRaw = raw.languages || [];
  return {
    linkedin_url, name, title,
    location: typeof location === 'string' ? location : '',
    schools: extractNames(schoolsRaw, 'schoolName', 'name', 'school'),
    companies: extractNames(companiesRaw, 'companyName', 'company', 'name'),
    industries: extractNames(industriesRaw, 'name'),
    languages: extractNames(languagesRaw, 'name', 'language'),
  };
}

async function runActor(actorId, input, timeout = 180000) {
  const token = process.env.APIFY_TOKEN;
  if (!token) throw new Error('APIFY_TOKEN not configured');
  const url = `${APIFY_BASE}/acts/${actorId}/run-sync-get-dataset-items`;
  const resp = await axios.post(url, input, {
    headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
    timeout,
    responseType: 'text',
  });
  const text = (resp.data || '').trim();
  if (!text || text.startsWith('<')) return [];
  try {
    const parsed = JSON.parse(text);
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}

async function scrapeProfile(profileUrl) {
  if (MOCK_MODE()) return { ...MOCK_PROFILE, linkedin_url: profileUrl };
  const key = { url: normalizeUrl(profileUrl) };
  return db.cachedCall('profile', key, parseInt(process.env.CACHE_TTL_PROFILE || 2592000), async () => {
    db.recordApifyCall(0.003);
    const items = await runActor(ACTOR_PROFILE, { urls: [{ url: profileUrl }] });
    return items[0] || {};
  }, db.recordCacheHit);
}

function guessLinkedinUrl(companyName) {
  const slug = (companyName || '')
    .toLowerCase()
    .replace(/&/g, 'and')
    .replace(/[^\w\s-]/g, '')
    .trim()
    .replace(/\s+/g, '-')
    .replace(/-+/g, '-');
  return `https://www.linkedin.com/company/${slug}/`;
}

async function searchCompanyEmployees(company, companyLinkedin, page = 1) {
  if (MOCK_MODE()) return MOCK_EMPLOYEES;
  const linkedinUrl = companyLinkedin || guessLinkedinUrl(company);
  const key = { url: normalizeUrl(linkedinUrl), page };
  return db.cachedCall('company_employees', key, parseInt(process.env.CACHE_TTL_COMPANY || 604800), async () => {
    db.recordApifyCall(0.11);
    const raw = await runActor(ACTOR_EMPLOYEES, { companies: [linkedinUrl], profileScraperMode: 'Short ($4 per 1k)', maxItems: 30 });
    return raw.map(normalizeEmployee);
  }, db.recordCacheHit);
}

async function enrichProfile(profileUrl) {
  if (MOCK_MODE()) return { ...MOCK_PROFILE, linkedin_url: profileUrl };
  const key = { url: normalizeUrl(profileUrl), full: true };
  return db.cachedCall('profile_full', key, parseInt(process.env.CACHE_TTL_PROFILE || 2592000), async () => {
    db.recordApifyCall(0.003);
    const items = await runActor(ACTOR_PROFILE, { urls: [{ url: profileUrl }] });
    return items[0] || {};
  }, db.recordCacheHit);
}

module.exports = { scrapeProfile, searchCompanyEmployees, enrichProfile, MOCK_MATCHES, MOCK_PROFILE };
