/**
 * GET /api/widget — public embeddable widget data feed.
 *
 *   - CORS: open to all origins (it's a public widget).
 *   - Cache: 15 minutes server-side + Cache-Control headers.
 *   - Rate limit: 60 req/min/Origin (60/min/IP if no Origin header).
 *
 * Response: tonight's top 3 grades, sport-filterable.
 */

const express = require('express');
const axios = require('axios');

const router = express.Router();

const API_BASE = process.env.API_BASE_URL || 'http://localhost:4000';
const CACHE_TTL_MS = 15 * 60_000;
const RATE_WINDOW_MS = 60_000;
const RATE_MAX = 60;

// Per-key sliding-window counter
const buckets = new Map();
function checkRate(key) {
  const now = Date.now();
  const arr = (buckets.get(key) || []).filter((t) => now - t < RATE_WINDOW_MS);
  if (arr.length >= RATE_MAX) return false;
  arr.push(now);
  buckets.set(key, arr);
  return true;
}
setInterval(() => {
  const now = Date.now();
  for (const [k, arr] of buckets.entries()) {
    const fresh = arr.filter((t) => now - t < RATE_WINDOW_MS);
    if (fresh.length === 0) buckets.delete(k);
    else buckets.set(k, fresh);
  }
}, RATE_WINDOW_MS).unref?.();

// Tiny in-memory cache keyed by sport
const cache = new Map();
function cacheGet(key) {
  const hit = cache.get(key);
  if (!hit) return null;
  if (Date.now() - hit.at > CACHE_TTL_MS) { cache.delete(key); return null; }
  return hit.value;
}
function cacheSet(key, value) {
  cache.set(key, { at: Date.now(), value });
}

const VALID_SPORTS = new Set(['nba', 'wnba', 'mlb']);

router.get('/', async (req, res) => {
  // CORS — open to all origins for the widget feed only. We DO NOT echo
  // request headers; we send an explicit allow-list of headers we accept.
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'GET');
  res.set('Access-Control-Allow-Headers', 'Content-Type');
  res.set('Vary', 'Origin');

  const origin = req.get('Origin') || (req.headers['x-forwarded-for'] || req.ip || 'unknown').toString();
  if (!checkRate(origin)) return res.status(429).json({ error: 'rate limit exceeded' });

  const sport = String(req.query.sport || 'nba').toLowerCase();
  if (!VALID_SPORTS.has(sport)) return res.status(400).json({ error: 'invalid sport' });

  const cached = cacheGet(sport);
  if (cached) {
    res.set('X-Cache', 'HIT');
    res.set('Cache-Control', 'public, max-age=900');
    return res.json(cached);
  }

  try {
    const r = await axios.get(`${API_BASE}/api/props/top-graded?limit=3&sport=${encodeURIComponent(sport)}`, { timeout: 8_000 });
    const props = Array.isArray(r.data?.props) ? r.data.props.slice(0, 3) : [];
    const payload = {
      sport,
      generated_at: new Date().toISOString(),
      props: props.map((p) => ({
        player: p.player_name || p.player,
        sport: p.sport,
        stat: p.stat_type || p.stat,
        direction: p.direction,
        line: p.line,
        grade: p.grade,
      })),
      link: 'https://vyndr.app',
    };
    cacheSet(sport, payload);
    res.set('X-Cache', 'MISS');
    res.set('Cache-Control', 'public, max-age=900');
    return res.json(payload);
  } catch (err) {
    return res.status(502).json({ error: 'upstream unavailable', detail: err?.message || 'unknown' });
  }
});

router.options('/', (_req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'GET');
  res.set('Access-Control-Allow-Headers', 'Content-Type');
  res.set('Access-Control-Max-Age', '86400');
  res.status(204).end();
});

module.exports = router;
