/**
 * Coach system + pace signal.
 *
 * Two signals exposed:
 *   coach_pace_delta:        coach's career pace MINUS current team's pace,
 *                            scaled by tenure (longer tenure = stronger
 *                            adjustment).
 *   coach_player_interaction: magnitude of system shift when the primary
 *                            player is OUT vs IN. Drives suppression for
 *                            role players when the star sits.
 *
 * Profiles live in `coach_profiles` (migration 017). On first read for a
 * team we check the table; if empty, fall back to the seed file at
 * src/config/coaches.json so launch isn't blocked on a fully populated
 * table.
 */

const path = require('path');
const fs = require('fs');
const { getSupabaseServiceClient } = require('../../utils/supabase');

let seedCache = null;
function loadSeed() {
  if (seedCache !== null) return seedCache;
  try {
    const raw = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'config', 'coaches.json'), 'utf8'));
    seedCache = { coaches: raw.coaches || [] };
  } catch {
    seedCache = { coaches: [] };
  }
  return seedCache;
}

function tenureAdjustment(games) {
  // Linear ramp to 1.0 over ~40 games — a coach inheriting a roster needs
  // time before the system actually drifts toward their preference.
  const g = Number(games) || 0;
  return Math.min(1.0, Math.max(0, g / 40));
}

async function getCoachProfile(sport, teamAbbr) {
  const supabase = getSupabaseServiceClient();
  const { data, error } = await supabase
    .from('coach_profiles')
    .select('coach_name, team, sport, career_avg_pace, current_team_pace, tenure_games, primary_player, system_style, without_primary_style, without_primary_pace_delta')
    .eq('team', teamAbbr)
    .eq('sport', sport)
    .maybeSingle();
  if (error) {
    console.warn('[coachSignals] profile lookup failed:', error.message);
  }
  if (data) return data;
  // Fall back to the seed file — same shape, different home.
  const seed = loadSeed();
  return seed.coaches.find((c) => c.team === teamAbbr && c.sport === sport) || null;
}

async function getCoachImpact(sport, teamAbbr, gameContext = {}) {
  const profile = await getCoachProfile(sport, teamAbbr);
  if (!profile) return null;

  const career = Number(profile.career_avg_pace);
  const team = Number(profile.current_team_pace);
  const paceDelta = Number.isFinite(career) && Number.isFinite(team) ? career - team : null;
  const tenureAdj = tenureAdjustment(profile.tenure_games);
  const adjustedPaceDelta = paceDelta != null ? paceDelta * tenureAdj : null;

  // Primary-player status comes from the caller — usually injuryParser told
  // them whether the star is OUT/DOUBTFUL.
  const primaryStatus = gameContext.primary_player_status ?? 'unknown';
  const systemOverride = primaryStatus === 'out' || primaryStatus === 'doubtful'
    ? profile.without_primary_style
    : null;
  const withoutPrimaryShift = primaryStatus === 'out'
    ? Number(profile.without_primary_pace_delta) || 0
    : 0;

  return {
    coach_name: profile.coach_name,
    system_style: profile.system_style ?? null,
    primary_player: profile.primary_player ?? null,
    pace_delta: paceDelta,
    tenure_adjustment: tenureAdj,
    adjusted_pace_delta: adjustedPaceDelta,
    primary_player_status: primaryStatus,
    system_override: systemOverride,
    without_primary_pace_shift: withoutPrimaryShift,
  };
}

module.exports = { getCoachImpact, getCoachProfile, tenureAdjustment, loadSeed };
