function detectCorrelations(analyzedLegs, spreads) {
  const flags = [];

  for (let i = 0; i < analyzedLegs.length; i++) {
    for (let j = i + 1; j < analyzedLegs.length; j++) {
      const a = analyzedLegs[i];
      const b = analyzedLegs[j];

      const aGame = a.reasoning?.steps?.season_avg ? getGameKey(a) : null;
      const bGame = b.reasoning?.steps?.season_avg ? getGameKey(b) : null;
      const sameGame = aGame && bGame && aGame === bGame;

      const aTeam = a._team;
      const bTeam = b._team;

      // 1. same_player_conflicting
      if (a.player.toLowerCase() === b.player.toLowerCase()) {
        if (isConflicting(a, b)) {
          flags.push({
            type: 'same_player_conflicting',
            legs: [i, j],
            detail: `${a.player}: ${a.stat_type} ${a.direction} conflicts with ${b.stat_type} ${b.direction}`,
            impact: 'major_negative',
          });
        } else {
          // 4. positive_correlation (same player, complementary)
          flags.push({
            type: 'positive_correlation',
            legs: [i, j],
            detail: `${a.player}: ${a.stat_type} ${a.direction} + ${b.stat_type} ${b.direction} are correlated`,
            impact: 'positive',
          });
        }
        continue;
      }

      if (!sameGame) continue;

      // 2. same_game_same_team
      if (aTeam && bTeam && aTeam === bTeam) {
        flags.push({
          type: 'same_game_same_team',
          legs: [i, j],
          detail: `${a.player} and ${b.player} are both ${aTeam} — usage overlap possible`,
          impact: 'minor_negative',
        });
        continue;
      }

      // 3. same_game_opposing_players
      if (a.stat_type === b.stat_type && a.direction === 'over' && b.direction === 'over') {
        flags.push({
          type: 'same_game_opposing_players',
          legs: [i, j],
          detail: `${a.player} and ${b.player} in same game, both ${a.stat_type} overs`,
          impact: 'minor_negative',
        });
      }
    }
  }

  // 5. blowout_cascade — 2+ legs from a high-spread game
  const gameLegs = groupByGame(analyzedLegs);
  for (const [gameKey, indices] of Object.entries(gameLegs)) {
    if (indices.length < 2) continue;
    const gameSpread = findSpreadForGame(analyzedLegs[indices[0]], spreads);
    if (gameSpread != null && Math.abs(gameSpread) > 8) {
      flags.push({
        type: 'blowout_cascade',
        legs: indices,
        detail: `${indices.length} legs from a game with ${gameSpread > 0 ? '+' : ''}${gameSpread} spread — blowout risk compounds`,
        impact: 'major_negative',
      });
    }
  }

  return flags;
}

function getGameKey(leg) {
  // Use home_team + away_team from reasoning to identify the game
  const sit = leg.reasoning?.steps?.situational;
  const lineCmp = leg.reasoning?.steps?.line_comparison;
  // Fallback: use the first line's game context
  // We'll use _gameTime attached by the scan service
  return leg._gameTime || null;
}

function isConflicting(a, b) {
  // Same player, opposite directions on related stats
  if (a.direction !== b.direction) return true;

  // Over points + under PRA (points is component of PRA)
  const complementary = [
    ['points', 'pra'], ['rebounds', 'pra'], ['assists', 'pra'],
  ];
  for (const [s1, s2] of complementary) {
    if ((a.stat_type === s1 && b.stat_type === s2) || (a.stat_type === s2 && b.stat_type === s1)) {
      if (a.direction !== b.direction) return true;
    }
  }

  return false;
}

function groupByGame(legs) {
  const groups = {};
  for (let i = 0; i < legs.length; i++) {
    const key = legs[i]._gameTime;
    if (!key) continue;
    if (!groups[key]) groups[key] = [];
    groups[key].push(i);
  }
  return groups;
}

function findSpreadForGame(leg, spreads) {
  if (!spreads || !leg._team) return null;
  const spread = spreads.find((s) =>
    s.home_team === leg._team || s.away_team === leg._team
  );
  if (!spread) return null;
  return spread.home_spread;
}

module.exports = { detectCorrelations };
