/**
 * /api/combat/:date + /api/fight/:id (Wave 6 — combat intelligence, honest v1).
 *
 * Fight-card discovery + tale-of-the-tape + best-effort moneyline / round-total
 * odds. FREE ESPN MMA feed for the cards; the paid odds-api feed for ML/round
 * totals is BEST-EFFORT + cached (never fails the card). Combat is NOT in the
 * snapshot/settle loop → NO settled grades here; method/round/KO are surfaced by
 * the frontend as honest "— data-limited", never fabricated.
 *
 * Response (cards):
 *   { date, events: [ { id, name, shortName, date, venue,
 *       bouts: [ { id, weightClass, rounds, status, fighters: [ …tale ],
 *                  odds: { moneyline, roundTotal } | null } ] } ], source }
 */

const express = require('express');
const combat = require('../services/adapters/combatAdapter');
const { createRateLimit } = require('../middleware/rateLimit');

const router = express.Router();
// Public throttle (60/min; ESPN is free, odds are cached — be respectful).
router.use(createRateLimit({ windowMs: 60_000, max: 60 }));

const MISSION_HEADER = { 'X-VYNDR-Mission': 'Styles make fights' };

// Attach cached/best-effort odds onto each bout of each event.
function attachOdds(events, oddsMap) {
  for (const ev of events || []) {
    for (const bout of ev.bouts || []) {
      const o = combat.matchBoutOdds(bout, oddsMap);
      bout.odds = o ? { moneyline: o.moneyline, roundTotal: o.roundTotal } : null;
    }
  }
  return events;
}

// GET /api/combat/:date — fight cards for an ET date (defaults to today).
router.get('/:date', async (req, res) => {
  const date = /^\d{4}-\d{2}-\d{2}$/.test(String(req.params.date || ''))
    ? req.params.date
    : combat.todayET();
  try {
    const [cards, oddsMap] = await Promise.all([
      combat.getFightCards(date),
      combat.getCombatOdds().catch(() => ({})),
    ]);
    attachOdds(cards.events, oddsMap);
    res.set('Cache-Control', 'public, max-age=300');
    return res.set(MISSION_HEADER).json(cards);
  } catch (err) {
    console.error('[combat/:date]', err && err.message);
    // The board is never a crash — honest empty on failure.
    return res.set(MISSION_HEADER).json({ date, events: [], source: 'espn' });
  }
});

module.exports = router;

// Separate router for /api/fight/:id (a single card by event id).
const fightRouter = express.Router();
fightRouter.use(createRateLimit({ windowMs: 60_000, max: 60 }));

fightRouter.get('/:id', async (req, res) => {
  const id = String(req.params.id || '').replace(/[^0-9]/g, '');
  if (!id) return res.status(404).set(MISSION_HEADER).json({ error: 'not found' });
  try {
    const [card, oddsMap] = await Promise.all([
      combat.getFightCard(id),
      combat.getCombatOdds().catch(() => ({})),
    ]);
    if (!card) return res.status(404).set(MISSION_HEADER).json({ error: 'card not found' });
    attachOdds([card], oddsMap);
    res.set('Cache-Control', 'public, max-age=300');
    return res.set(MISSION_HEADER).json({ event: card, source: 'espn' });
  } catch (err) {
    console.error('[fight/:id]', err && err.message);
    return res.status(404).set(MISSION_HEADER).json({ error: 'card not found' });
  }
});

module.exports.fightRouter = fightRouter;
