// Thin client over the Job-bot webapp endpoints (per docs/job-bot-contract.md).
//
// Every method has TWO modes:
//   1. LIVE — when process.env.JOBBOT_BASE is set, hits the real HTTPS API
//      with Bearer auth using process.env.WHATSAPP_ORCHESTRATOR_TOKEN.
//   2. MOCK — when JOBBOT_BASE is unset, returns deterministic fixtures so
//      the WhatsApp side is fully testable end-to-end before the Job-bot
//      webapp ships. Mock mode is keyed off env, NOT off SILVER_TEST_MODE,
//      so prod can deploy "ahead" of the Job-bot side without breaking.
//
// Linear: ECO-8 (contract), ECO-15 (token mint), ECO-16/17/18 (roles + tracker)

// fetch is available as a global in Node 18+ — no import needed.

const JOBBOT_BASE = () => process.env.JOBBOT_BASE || null;
const TOKEN = () => process.env.WHATSAPP_ORCHESTRATOR_TOKEN || null;

function isLive() {
  return !!JOBBOT_BASE();
}

async function call(method, path, body = null) {
  const url = `${JOBBOT_BASE().replace(/\/$/, '')}${path}`;
  const headers = {
    'Authorization': `Bearer ${TOKEN() || ''}`,
    'Accept': 'application/json',
  };
  const init = { method, headers };
  if (body !== null) {
    headers['Content-Type'] = 'application/json';
    init.body = JSON.stringify(body);
  }
  const res = await fetch(url, init);
  const text = await res.text();
  let parsed = null;
  if (text) { try { parsed = JSON.parse(text); } catch { parsed = { _raw: text }; } }
  if (!res.ok) {
    const err = new Error(`Job-bot ${method} ${path} → ${res.status}`);
    err.status = res.status;
    err.body = parsed;
    throw err;
  }
  return parsed;
}

// ── Endpoint 1: POST /auth/whatsapp-token ───────────────────────────────────
// Mints a one-time token bound to phone+userId, 30-min TTL by default.
// We pass our own pre-minted token through so the WhatsApp side and Job-bot
// agree on the value (the WhatsApp side already persists in silver.json).

export async function registerToken({ phone, userId, token, ttlMinutes = 30 }) {
  if (!isLive()) {
    return {
      mock: true,
      token,
      expiresAt: new Date(Date.now() + ttlMinutes * 60_000).toISOString(),
      url: `https://jobbot.example.test/plan?t=${token}`,
    };
  }
  return await call('POST', '/auth/whatsapp-token', { phone, userId, token, ttlMinutes });
}

// ── Endpoint 2: GET /career-plan/:userId ────────────────────────────────────

export async function getCareerPlan(userId) {
  if (!isLive()) {
    return {
      mock: true,
      userId,
      status: 'generated',
      generatedAt: new Date().toISOString(),
      inputs: { targetRoles: [], targetGeos: [], salaryFloor: null, languages: [], nonNegotiables: [] },
      summary: '[mock career plan summary]',
      url: `https://jobbot.example.test/plan/${userId}`,
    };
  }
  return await call('GET', `/career-plan/${encodeURIComponent(userId)}`);
}

// ── Endpoint 3: GET /career-plan/:userId/status ─────────────────────────────

export async function getCareerPlanStatus(userId) {
  if (!isLive()) return { mock: true, userId, status: 'generated' };
  return await call('GET', `/career-plan/${encodeURIComponent(userId)}/status`);
}

// ── Endpoint 4: GET /roles?userId=&limit=10 ─────────────────────────────────

export async function getRoles(userId, { limit = 10, excludeJobbotRoleIds = [] } = {}) {
  if (!isLive()) {
    // Mock returns a small deterministic batch so dev can exercise the full
    // weekly-delivery flow. Tests assert against these IDs.
    const mockRoles = [
      { jobbotRoleId: 'mock_r_001', title: 'Senior Product Manager', company: 'Acme',  location: 'Zurich, CH (Hybrid)', applyUrl: 'https://acme.example/jobs/001', description: 'B2B SaaS PM role.', matchScore: 0.84, salaryRange: '130-160k CHF' },
      { jobbotRoleId: 'mock_r_002', title: 'Growth Marketing Lead',  company: 'Beta',  location: 'Remote-EU',           applyUrl: 'https://beta.example/jobs/002',  description: 'Growth lead role.', matchScore: 0.78, salaryRange: '95-120k EUR' },
      { jobbotRoleId: 'mock_r_003', title: 'Operations Manager',     company: 'Gamma', location: 'Lisbon, PT',          applyUrl: 'https://gamma.example/jobs/003', description: 'Logistics ops.',    matchScore: 0.72, salaryRange: '60-80k EUR' },
      { jobbotRoleId: 'mock_r_004', title: 'Senior PM (Fintech)',    company: 'Delta', location: 'Remote-EU',           applyUrl: 'https://delta.example/jobs/004', description: 'Fintech PM.',       matchScore: 0.81, salaryRange: '120-150k EUR' },
      { jobbotRoleId: 'mock_r_005', title: 'Head of Operations',     company: 'Eps',   location: 'Zurich, CH',          applyUrl: 'https://eps.example/jobs/005',   description: 'Head of ops.',      matchScore: 0.70, salaryRange: '140-180k CHF' },
    ];
    const exclude = new Set(excludeJobbotRoleIds);
    const filtered = mockRoles.filter(r => !exclude.has(r.jobbotRoleId)).slice(0, limit);
    return {
      mock: true,
      userId,
      roles: filtered,
      thinPipelineWarning: filtered.length < 5,
    };
  }
  const qs = new URLSearchParams({ userId, limit: String(limit) });
  if (excludeJobbotRoleIds.length) qs.set('excludeJobbotRoleIds', excludeJobbotRoleIds.join(','));
  return await call('GET', `/roles?${qs.toString()}`);
}

// ── Endpoint 5: POST /tracker/applied ───────────────────────────────────────

export async function logApplied({ userId, jobbotRoleId, appliedAt = null, source = 'whatsapp' }) {
  if (!isLive()) {
    return { mock: true, ok: true, trackerId: `mock_t_${Date.now()}` };
  }
  return await call('POST', '/tracker/applied', {
    userId, jobbotRoleId, appliedAt: appliedAt || new Date().toISOString(), source,
  });
}

// ── Endpoint 6: POST /tracker/status ────────────────────────────────────────

export async function updateTrackerStatus({ userId, jobbotRoleId, status, note = null, at = null }) {
  if (!isLive()) {
    return { mock: true, ok: true, previousStatus: 'unknown' };
  }
  return await call('POST', '/tracker/status', {
    userId, jobbotRoleId, status, note, at: at || new Date().toISOString(),
  });
}

// ── Endpoint 7: GET /tracker/:userId ────────────────────────────────────────

export async function getTracker(userId) {
  if (!isLive()) {
    return { mock: true, userId, applications: [] };
  }
  return await call('GET', `/tracker/${encodeURIComponent(userId)}`);
}

export const __forTest = { isLive };
