import { query } from '../../db';
import { alerter } from '../../services/alerter';

interface DecaySignal {
  league: string;
  metric: string;
  value: number;
  threshold: number;
  severity: 'warn' | 'critical';
}

export async function runEdgeDecay(): Promise<void> {
  const signals: DecaySignal[] = [];
  const leagues = ['nba', 'nfl', 'nhl', 'mlb', 'ncaab', 'ncaaf'];

  for (const league of leagues) {
    // Check positive CLV rate over 100 picks
    const rate100 = await query(`
      SELECT AVG(CASE WHEN clv > 0 THEN 1.0 ELSE 0.0 END) as rate, COUNT(*) as n
      FROM (SELECT clv FROM sc_clv_records WHERE league = $1 AND clv IS NOT NULL ORDER BY created_at DESC LIMIT 100) sub
    `, [league]);

    if (rate100.rows[0]?.n >= 50) {
      const rate = parseFloat(rate100.rows[0].rate);
      if (rate < 0.48) {
        signals.push({ league, metric: 'positive_clv_rate_100', value: rate, threshold: 0.48, severity: 'critical' });
      } else if (rate < 0.52) {
        signals.push({ league, metric: 'positive_clv_rate_100', value: rate, threshold: 0.52, severity: 'warn' });
      }
    }

    // Check positive CLV rate over 200 picks
    const rate200 = await query(`
      SELECT AVG(CASE WHEN clv > 0 THEN 1.0 ELSE 0.0 END) as rate, COUNT(*) as n
      FROM (SELECT clv FROM sc_clv_records WHERE league = $1 AND clv IS NOT NULL ORDER BY created_at DESC LIMIT 200) sub
    `, [league]);

    if (rate200.rows[0]?.n >= 100) {
      const rate = parseFloat(rate200.rows[0].rate);
      if (rate < 0.48) {
        signals.push({ league, metric: 'positive_clv_rate_200', value: rate, threshold: 0.48, severity: 'critical' });
      }
    }

    // Check average CLV over 100 picks
    const avg100 = await query(`
      SELECT AVG(clv) as avg_clv, COUNT(*) as n
      FROM (SELECT clv FROM sc_clv_records WHERE league = $1 AND clv IS NOT NULL ORDER BY created_at DESC LIMIT 100) sub
    `, [league]);

    if (avg100.rows[0]?.n >= 50) {
      const avg = parseFloat(avg100.rows[0].avg_clv);
      if (avg < 0) {
        signals.push({ league, metric: 'avg_clv_100', value: avg, threshold: 0, severity: 'critical' });
      } else if (avg < 0.3) {
        signals.push({ league, metric: 'avg_clv_100', value: avg, threshold: 0.3, severity: 'warn' });
      }
    }

    // Check CLV trend (slope over last 50 picks)
    const trendResult = await query(`
      SELECT clv, ROW_NUMBER() OVER (ORDER BY created_at ASC) as rn
      FROM (SELECT clv, created_at FROM sc_clv_records WHERE league = $1 AND clv IS NOT NULL ORDER BY created_at DESC LIMIT 50) sub
    `, [league]);

    if (trendResult.rows.length >= 30) {
      // Simple linear regression slope
      const n = trendResult.rows.length;
      let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;
      for (const row of trendResult.rows) {
        const x = parseInt(row.rn);
        const y = parseFloat(row.clv);
        sumX += x; sumY += y; sumXY += x * y; sumXX += x * x;
      }
      const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);

      if (slope < -0.02) {
        signals.push({ league, metric: 'clv_trend_slope', value: slope, threshold: -0.02, severity: slope < -0.05 ? 'critical' : 'warn' });
      }
    }
  }

  // Update edge health score in global state
  const criticalCount = signals.filter(s => s.severity === 'critical').length;
  const warnCount = signals.filter(s => s.severity === 'warn').length;
  let edgeScore = 100 - (criticalCount * 20) - (warnCount * 5);
  edgeScore = Math.max(0, Math.min(100, edgeScore));

  await query(
    `UPDATE sc_global_state SET edge_health_score = $1, last_updated = NOW(), updated_by = 'edge-decay' WHERE id = 'primary'`,
    [edgeScore]
  );

  // If critical signals, set mode to cautious
  if (criticalCount >= 2) {
    await query(
      `UPDATE sc_global_state SET mode = 'cautious', last_updated = NOW() WHERE id = 'primary' AND mode = 'normal'`
    );
    await alerter.alertAdmins(
      'critical',
      `Edge decay detected! ${criticalCount} critical signals across leagues.\n\nSignals:\n${signals.filter(s => s.severity === 'critical').map(s => `• ${s.league}: ${s.metric} = ${s.value.toFixed(4)} (threshold: ${s.threshold})`).join('\n')}\n\nSystem mode set to CAUTIOUS.`,
      { signals, edge_score: edgeScore }
    );
  } else if (signals.length > 0) {
    await alerter.logEvent(
      'edge_decay_check', 'info', 'edge-decay',
      `Edge check: ${signals.length} signals (${criticalCount} critical, ${warnCount} warn). Score: ${edgeScore}`,
      { signals, edge_score: edgeScore }
    );
  }
}
