/**
 * Pinnacle sharp-reference adapter.
 *
 * Pinnacle's lines are the sharp benchmark every other book chases. We don't
 * scrape Pinnacle's site directly (TOS-grey, anti-bot). Instead we read from
 * a configurable upstream — by default the public-facing `pinnacle.com` REST
 * API used by their own site. If `PINNACLE_API_BASE` is set in env we use
 * that (typical: a paid odds provider that proxies Pinnacle).
 *
 * The adapter implements the OddsAdapter contract — failure mode is an empty
 * array, not a thrown error, so the orchestrator's `sources` array reflects
 * who actually contributed.
 */

const axios = require('axios');
const rateLimiter = require('../rateLimiter');
const breaker = require('../circuitBreaker');

const SOURCE = 'pinnacle';
const HTTP_TIMEOUT_MS = 10_000;

const SPORT_IDS = Object.freeze({
  // These are Pinnacle's internal sport IDs as observed on pinnacle.com's
  // public guest API. They occasionally change.
  nba:  4,
  wnba: 4,
  mlb:  9,
  nhl:  17,
  nfl:  29,
  mma:  22,
  golf: 12,
});

const BASE = process.env.PINNACLE_API_BASE || 'https://guest.api.arcadia.pinnacle.com/0.1';

function buildHeaders() {
  // Pinnacle's guest API expects an X-API-Key header on calls; the public
  // site embeds it in JS. If you have one, set PINNACLE_API_KEY.
  const key = process.env.PINNACLE_API_KEY;
  const headers = {
    'User-Agent': 'VYNDR/1.0',
    Accept: 'application/json',
  };
  if (key) headers['X-API-Key'] = key;
  return headers;
}

async function getGames(sport) {
  const sportId = SPORT_IDS[sport];
  if (!sportId) {
    const err = new Error(`pinnacle adapter does not support sport: ${sport}`);
    err.skipBreaker = true;
    throw err;
  }
  if (!process.env.PINNACLE_API_KEY) {
    // Without an API key Pinnacle's guest endpoint refuses requests. Return
    // empty so the orchestrator surfaces a clean 'pinnacle: 0 games' status
    // rather than tripping the breaker.
    return [];
  }

  await rateLimiter.take(SOURCE);
  return breaker.call(SOURCE, async () => {
    const url = `${BASE}/sports/${sportId}/matchups`;
    const res = await axios.get(url, {
      timeout: HTTP_TIMEOUT_MS,
      headers: buildHeaders(),
      validateStatus: (s) => s >= 200 && s < 500,
    });
    if (res.status >= 400) {
      const err = new Error(`pinnacle returned ${res.status}`);
      err.upstream = SOURCE;
      throw err;
    }
    const matchups = Array.isArray(res.data) ? res.data : [];
    return matchups.map((m) => ({
      game_id: String(m.id ?? m.matchupId ?? ''),
      sport,
      home: m.participants?.find?.((p) => p.alignment === 'home')?.name || null,
      away: m.participants?.find?.((p) => p.alignment === 'away')?.name || null,
      start_time: m.startTime || null,
      status: m.status || null,
      source: SOURCE,
      fetched_at: new Date().toISOString(),
    }));
  });
}

async function getPlayerProps(/* sport */) {
  // Pinnacle does carry player props but they live behind a separate prices
  // endpoint and are only emitted close to game time. Wired here as TODO so
  // the orchestrator just gets an empty array until we light it up.
  return [];
}

module.exports = { name: SOURCE, getGames, getPlayerProps, SPORT_IDS };
