// FRED — Federal Reserve Economic Data
// 840,000+ time series. Free API key required.
// Key indicators: yield curve, CPI, unemployment, money supply, GDP, fed funds rate

import { safeFetch, today, daysAgo } from '../utils/fetch.mjs';

const BASE = 'https://api.stlouisfed.org/fred';

// Key series IDs for macro intelligence
const KEY_SERIES = {
  // Yield curve & rates
  DFF: 'Fed Funds Rate',
  DGS2: '2-Year Treasury Yield',
  DGS10: '10-Year Treasury Yield',
  DGS30: '30-Year Treasury Yield',
  T10Y2Y: '10Y-2Y Spread (Yield Curve)',
  T10Y3M: '10Y-3M Spread',
  // Inflation
  CPIAUCSL: 'CPI All Items',
  CPILFESL: 'Core CPI (ex Food & Energy)',
  PCEPI: 'PCE Price Index',
  MICH: 'Michigan Inflation Expectations',
  // Labor
  UNRATE: 'Unemployment Rate',
  PAYEMS: 'Nonfarm Payrolls',
  ICSA: 'Initial Jobless Claims',
  // Money & credit
  M2SL: 'M2 Money Supply',
  WALCL: 'Fed Balance Sheet Total Assets',
  // Fear gauges
  VIXCLS: 'VIX (Fear Index)',
  BAMLH0A0HYM2: 'High Yield Spread (Credit Stress)',
  // Commodities via FRED
  DCOILWTICO: 'WTI Crude Oil',
  GOLDAMGBD228NLBM: 'Gold Price (London Fix)',
  // Housing
  MORTGAGE30US: '30-Year Mortgage Rate',
  // Global
  DTWEXBGS: 'USD Trade Weighted Index',
};

// Get latest value for a series
async function getSeriesLatest(seriesId, apiKey) {
  const params = new URLSearchParams({
    series_id: seriesId,
    api_key: apiKey,
    file_type: 'json',
    sort_order: 'desc',
    limit: '5',
    observation_start: daysAgo(90),
  });
  return safeFetch(`${BASE}/series/observations?${params}`);
}

// Briefing — pull all key indicators
export async function briefing(apiKey) {
  if (!apiKey) {
    return {
      source: 'FRED',
      error: 'No FRED API key. Get one free at https://fred.stlouisfed.org/docs/api/api_key.html',
      hint: 'Set FRED_API_KEY environment variable',
    };
  }

  const entries = Object.entries(KEY_SERIES);
  const results = await Promise.all(
    entries.map(async ([id, label]) => {
      const data = await getSeriesLatest(id, apiKey);
      const obs = data?.observations;
      if (!obs?.length) return { id, label, value: null, date: null, recent: [] };
      const latest = obs.find(o => o.value !== '.');
      const validObs = obs.filter(o => o.value !== '.');
      return {
        id,
        label,
        value: latest ? parseFloat(latest.value) : null,
        date: latest?.date || null,
        recent: validObs.slice(0, 5).map(o => parseFloat(o.value)),
      };
    })
  );

  // Compute derived signals
  const get = (id) => results.find(r => r.id === id)?.value;
  const yieldCurve10y2y = get('T10Y2Y');
  const yieldCurve10y3m = get('T10Y3M');
  const vix = get('VIXCLS');
  const hySpread = get('BAMLH0A0HYM2');

  const signals = [];
  if (yieldCurve10y2y !== null && yieldCurve10y2y < 0) signals.push('YIELD CURVE INVERTED (10Y-2Y) — recession signal');
  if (yieldCurve10y3m !== null && yieldCurve10y3m < 0) signals.push('YIELD CURVE INVERTED (10Y-3M) — stronger recession signal');
  if (vix !== null && vix > 30) signals.push(`VIX ELEVATED at ${vix} — high fear/volatility`);
  if (vix !== null && vix > 40) signals.push(`VIX EXTREME at ${vix} — crisis-level fear`);
  if (hySpread !== null && hySpread > 5) signals.push(`HIGH YIELD SPREAD WIDE at ${hySpread}% — credit stress`);

  return {
    source: 'FRED',
    timestamp: new Date().toISOString(),
    indicators: results.filter(r => r.value !== null),
    signals,
  };
}

if (process.argv[1]?.endsWith('fred.mjs')) {
  const data = await briefing(process.env.FRED_API_KEY);
  console.log(JSON.stringify(data, null, 2));
}
