export interface VolatilityResult {
  label: 'High' | 'Medium' | 'Low' | '—';
  monthlyVol: number;
}

/**
 * Computes 30-day rolling volatility from an array of prices using
 * log-return standard deviation scaled to a monthly expectation.
 *
 * @param prices - Ordered array of market prices (oldest → newest)
 * @returns label ('High' | 'Medium' | 'Low' | '—') and monthlyVol (0–1 range)
 */
export function computeVolatility(prices: number[]): VolatilityResult {
  if (prices.length < 2) return { label: '—', monthlyVol: 0 };

  const returns: number[] = [];
  for (let i = 1; i < prices.length; i++) {
    returns.push(Math.log(prices[i] / prices[i - 1]));
  }

  const mean     = returns.reduce((a, b) => a + b, 0) / returns.length;
  const variance = returns.reduce((sum, r) => sum + (r - mean) ** 2, 0) / (returns.length - 1);
  const monthlyVol = Math.sqrt(variance) * Math.sqrt(30);

  const label: VolatilityResult['label'] =
    monthlyVol >= 0.30 ? 'High'
  : monthlyVol >= 0.15 ? 'Medium'
  : 'Low';

  return { label, monthlyVol: Math.round(monthlyVol * 100) / 100 };
}

/**
 * Groups a list of price-history rows by condition and computes volatility
 * for each, filtered to a rolling window.
 *
 * @param rows      - Array of { condition, calculatedAt, marketPrice }
 * @param windowMs  - Rolling window in milliseconds (default: 30 days)
 */
export function volatilityByCondition(
  rows: Array<{ condition: string; calculatedAt: string | Date | null; marketPrice: number | string | null }>,
  windowMs = 30 * 86_400_000,
): Record<string, VolatilityResult> {
  const cutoff = new Date(Date.now() - windowMs);
  const grouped: Record<string, number[]> = {};

  for (const row of rows) {
    if (row.marketPrice == null || !row.calculatedAt) continue;
    if (new Date(row.calculatedAt) < cutoff) continue;
    const price = Number(row.marketPrice);
    if (price <= 0) continue;
    if (!grouped[row.condition]) grouped[row.condition] = [];
    grouped[row.condition].push(price);
  }

  const result: Record<string, VolatilityResult> = {};
  for (const [condition, prices] of Object.entries(grouped)) {
    result[condition] = computeVolatility(prices);
  }
  return result;
}