/**
 * ParlayAPI — historical prop archive.
 *
 * Free tier: 1,000 credits/month. 3.7M historical prop closing records,
 * 1.56M game-line archive. "Drop-in for the-odds-api, up to 6× cheaper."
 *
 * When called:
 *   1. Historical pull script (scripts/pull-parlayapi-history.js) — bulk
 *   2. Trap detection — query historical hit rates for a player/stat combo
 *   3. Feature enrichment — historical line accuracy
 *
 * NOT used during real-time grading (credit-limited).
 * Historical data lands in Supabase `historical_props` (migration 017).
 *
 * Failure modes mirror sharpApiAdapter:
 *   - 429 → back off, no stale cache (historical data isn't time-sensitive)
 *   - 5xx → circuit breaker (3 fails → open 60s)
 *   - timeout → 10s, breaker counts it
 */

const axios = require('axios');
const { createLimiter, createCircuitBreaker } = require('../../utils/rateLimiter');
const { cacheGet, cacheSet } = require('../../utils/redis');
// Session 21 — gateway wrap. ParlayAPI is the historical-archive
// source (1K credits/month). The in-process limiter caps to
// 5 req/min so we can spread the monthly budget; the gateway
// counter is what the admin dashboard reads against.
const gateway = require('../providerGateway');

const SOURCE = 'parlayapi';
const HTTP_TIMEOUT_MS = 10_000;
const CACHE_TTL_SECONDS = 24 * 60 * 60;  // 24h — historical data is immutable

const BASE_URL = process.env.PARLAYAPI_BASE_URL || 'https://api.parlayapi.io/v1';

// Conservative budget: 5 req/min lets us spread 1,000 credits/month across the
// month (~33/day). Bulk script overrides with its own pacing.
const limiter = createLimiter({ tokensPerInterval: 5, interval: 60_000 });
const breaker = createCircuitBreaker({ failureThreshold: 3, resetTimeout: 60_000 });

const SPORT_KEYS = Object.freeze({
  nba:    'basketball_nba',
  wnba:   'basketball_wnba',
  mlb:    'baseball_mlb',
  nfl:    'americanfootball_nfl',
  nhl:    'icehockey_nhl',
  ncaab:  'basketball_ncaab',
  ncaafb: 'americanfootball_ncaaf',
});

function configured() {
  return !!process.env.PARLAYAPI_KEY;
}

function sportKey(sport) {
  const key = SPORT_KEYS[sport];
  if (!key) throw new Error(`Unsupported sport: ${sport}`);
  return key;
}

async function fetchWithGuards(url, params, cacheKey) {
  if (!configured()) return null;
  const cached = await cacheGet(cacheKey);
  if (cached) return cached;

  await limiter.waitForToken();
  try {
    const data = await breaker.call(async () => {
      const res = await gateway.fetch(
        'parlayapi',
        () => axios.get(url, {
          params,
          headers: { 'X-Api-Key': process.env.PARLAYAPI_KEY },
          timeout: HTTP_TIMEOUT_MS,
          validateStatus: (s) => (s >= 200 && s < 300) || s === 429,
        }),
        { capability: 'historical_props', sport: params && params.sport },
      );
      if (res.status === 429) {
        const err = new Error('parlayapi rate limited');
        err.code = 'PARLAYAPI_429';
        throw err;
      }
      return res.data;
    });
    await cacheSet(cacheKey, data, CACHE_TTL_SECONDS);
    return data;
  } catch (err) {
    if (err?.code === 'CIRCUIT_OPEN') return null;
    console.warn(`[${SOURCE}] fetch failed for ${cacheKey}:`, err?.message);
    return null;
  }
}

function normalizeHistoricalProp(raw, sport) {
  return {
    sport,
    game_date: raw.game_date ?? raw.date ?? null,
    player_name: raw.player ?? raw.player_name ?? null,
    stat_type: raw.stat_type ?? raw.market ?? null,
    line: Number(raw.line ?? raw.point ?? null),
    closing_line: Number(raw.closing_line ?? raw.close ?? null) || null,
    result: raw.result ?? raw.outcome ?? null,
    source: SOURCE,
  };
}

async function getHistoricalProps(sport, playerName, statType, limit = 50) {
  const key = sportKey(sport);
  const cacheKey = `parlayapi:hist:${sport}:${playerName}:${statType}:${limit}`;
  const data = await fetchWithGuards(
    `${BASE_URL}/historical/player_props`,
    { sport: key, player: playerName, stat_type: statType, limit },
    cacheKey
  );
  if (!data) return [];
  const raw = data.props || data.results || data.data || [];
  return Array.isArray(raw) ? raw.map((r) => normalizeHistoricalProp(r, sport)) : [];
}

async function getClosingLines(sport, gameDate) {
  const key = sportKey(sport);
  const cacheKey = `parlayapi:close:${sport}:${gameDate}`;
  const data = await fetchWithGuards(
    `${BASE_URL}/historical/closing_lines`,
    { sport: key, date: gameDate },
    cacheKey
  );
  if (!data) return [];
  const raw = data.lines || data.results || data.data || [];
  return Array.isArray(raw) ? raw : [];
}

module.exports = {
  configured,
  getHistoricalProps,
  getClosingLines,
  __internals: { limiter, breaker, SPORT_KEYS, BASE_URL, normalizeHistoricalProp },
};
