'use strict';

const MOCK_MODE = process.env.OUTREACH_MOCK_MODE !== 'false';
const APOLLO_KEY = process.env.APOLLO_API_KEY || '';
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || '';

// ── Mock data ─────────────────────────────────────────────────────────────────

const MOCK_MATCHES = [
    {
        rank: 1,
        name: 'Anna Jensen',
        title: 'Senior PM, Google Cloud',
        linkedin_url: 'https://linkedin.com/in/anna-jensen',
        location: 'Copenhagen, Denmark',
        score: 92,
        connection_type: 'strong_match',
        match_reasons: [
            { type: 'school', detail: 'Both attended DTU' },
            { type: 'location', detail: 'Both based in Copenhagen / Nordics' },
        ],
        approach_angle: 'Lead with your shared DTU background and Nordics connection; ask about her path from consumer tech to Google Cloud.',
        draft_message: 'Hi Anna — fellow DTU alum, now building SaaS/fintech out of Lisbon. Eyeing PM at Google Cloud; would value your advice on the path in as a Nordic PM. Open to 15 min?',
    },
    {
        rank: 2,
        name: 'Carlos Mendez',
        title: 'Product Lead, Google Payments',
        linkedin_url: 'https://linkedin.com/in/carlosmendez',
        location: 'Madrid, Spain',
        score: 78,
        connection_type: 'strong_match',
        match_reasons: [
            { type: 'company', detail: 'Both previously worked at Rappi' },
            { type: 'industry', detail: 'Both in fintech/payments' },
            { type: 'language', detail: 'Both speak Spanish' },
        ],
        approach_angle: 'Your Rappi overlap is an easy opener — mention the LatAm fintech scene and ask about the move to Google Payments.',
        draft_message: 'Hi Carlos — ex-Rappi here (LatAm fintech). Thinking about a jump into Google Payments PM; would love your advice on making that shift from startup to Google scale. Open to a chat?',
    },
    {
        rank: 3,
        name: 'Miguel Santos',
        title: 'PM, Google Workspace',
        linkedin_url: 'https://linkedin.com/in/miguel-santos',
        location: 'Lisbon, Portugal',
        score: 64,
        connection_type: 'moderate_match',
        match_reasons: [
            { type: 'location', detail: 'Both based in Lisbon' },
        ],
        approach_angle: 'Same city — propose a quick coffee in Lisbon to hear about PM culture at Google.',
        draft_message: 'Hi Miguel — also Lisbon-based, building in SaaS. Looking at PM at Google Workspace; would value your advice on interviewing and what the team looks for. Coffee in Lisbon?',
    },
];

// ── Claude system prompt ──────────────────────────────────────────────────────

const SCORE_SYSTEM = `You rank people at a target company by how likely they are to (a) accept a
LinkedIn connection from the applicant and (b) be helpful in the applicant's
job search. Prioritize: direct_connection > shared work history > shared school
> shared location > shared industry > shared language > shared skills.

Return strictly this JSON shape (no prose):
{
  "matches": [
    {
      "name": string,
      "title": string,
      "linkedin_url": string,
      "location": string | null,
      "score": int 1-100,
      "connection_type": "direct_connection" | "strong_match" | "moderate_match",
      "match_reasons": [
        {"type": "direct_connection"|"school"|"company"|"location"|"industry"|"language"|"skill"|"role",
         "detail": string}
      ],
      "approach_angle": string,
      "draft_message": string
    }
  ]
}

Rules:
- Output 3-5 people total, ranked best-first.
- A candidate with is_direct_connection: true MUST get connection_type "direct_connection" and score >=90.
- Keep match_reasons concrete ("Both attended DTU"), not generic ("Shared background").
- approach_angle: one sentence of internal strategy. Explains WHY the opener works.

draft_message — the actual LinkedIn connection note the applicant will send.
HARD RULES:
  1. TARGET 160-180 characters. ABSOLUTE MAX 200 including spaces.
  2. Written in FIRST PERSON from the applicant to the recipient.
  3. Start with "Hi <first name>," or "Hi <first name> —".
  4. Must reference at least ONE specific detail from the applicant's background.
  5. Must reference at least ONE specific detail tied to the recipient's role or focus area.
  6. Must explicitly ASK FOR ADVICE. Not a job, not a referral.
  7. Direct. No filler, no adjectives for their work.
  8. MUST end with a short, concrete question or invitation.

Good example (152 chars):
"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?"`;

// ── Helpers ───────────────────────────────────────────────────────────────────



function _extractJson(text) {
    text = text.trim();
    const fence = text.match(/```(?:json)?\s*([\s\S]+?)```/);
    if (fence) text = fence[1].trim();
    try { return JSON.parse(text); } catch {}
    const obj = text.match(/\{[\s\S]*\}/);
    if (obj) return JSON.parse(obj[0]);
    throw new Error('No JSON in Claude response');
}

function _clampMessage(text) {
    if (typeof text !== 'string') return '';
    text = text.trim();
    if (text.length <= 200) return text;
    let trimmed = text.slice(0, 199);
    const lastSpace = trimmed.lastIndexOf(' ');
    if (lastSpace > 119) trimmed = trimmed.slice(0, lastSpace);
    return trimmed.replace(/[,.;:— ]+$/, '') + '…';
}

// ── Apollo ────────────────────────────────────────────────────────────────────

async function _searchCompanyEmployees(companyName) {
    if (!APOLLO_KEY) throw new Error('APOLLO_API_KEY not configured');
    const res = await fetch('https://api.apollo.io/v1/mixed_people/search', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-Api-Key': APOLLO_KEY },
        body: JSON.stringify({ q_organization_name: companyName, per_page: 25, page: 1 }),
        signal: AbortSignal.timeout(20_000),
    });
    if (!res.ok) throw new Error(`Apollo error ${res.status}: ${await res.text().catch(() => '')}`);
    const data = await res.json();
    return (data.people || []).map(p => ({
        linkedin_url: p.linkedin_url || '',
        name:         `${p.first_name || ''} ${p.last_name || ''}`.trim(),
        title:        p.title || '',
        location:     [p.city, p.state, p.country].filter(Boolean).join(', '),
        schools:      [],
        companies:    [p.organization_name].filter(Boolean),
        industries:   [],
        languages:    [],
    }));
}

// ── Claude ────────────────────────────────────────────────────────────────────

async function _rankWithClaude(employees, { target_company, target_role, linkedin_url }) {
    if (!ANTHROPIC_API_KEY) throw new Error('ANTHROPIC_API_KEY not configured');
    const payload = {
        applicant: { linkedin_url: linkedin_url || null, target_role: target_role || null },
        target_company,
        candidates: employees,
    };
    const res = await fetch('https://api.anthropic.com/v1/messages', {
        method: 'POST',
        headers: {
            'x-api-key': ANTHROPIC_API_KEY,
            'anthropic-version': '2023-06-01',
            'content-type': 'application/json',
        },
        body: JSON.stringify({
            model: 'claude-sonnet-4-6',
            max_tokens: 2048,
            system: SCORE_SYSTEM,
            messages: [{ role: 'user', content: 'Data:\n' + JSON.stringify(payload, null, 2) }],
        }),
        signal: AbortSignal.timeout(60_000),
    });
    if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(`Anthropic error ${res.status}: ${err.error?.message || 'unknown'}`);
    }
    const data = await res.json();
    const parsed = _extractJson(data.content[0].text);
    return (parsed.matches || []).map((m, i) => ({
        ...m,
        rank: i + 1,
        draft_message: _clampMessage((m.draft_message || '').trim()),
    }));
}

// ── Public API ────────────────────────────────────────────────────────────────

async function runOutreachDiscovery({ target_company, target_role, linkedin_url }) {
    if (MOCK_MODE) {
        await new Promise(r => setTimeout(r, 1500));
        return MOCK_MATCHES.slice(0, 3);
    }

    const employees = await _searchCompanyEmployees(target_company);
    const matches = await _rankWithClaude(employees, { target_company, target_role, linkedin_url });
    return matches.slice(0, 3);
}

module.exports = { runOutreachDiscovery };
