/**
 * RIE Signal: DVP (Defense vs Position)
 *
 * Promoted to first-class signal. Quantifies overall defensive weakness
 * for both teams in the matchup. More EASY-tier positions = higher score.
 */

import { Signal, SignalResult, MatchupContext } from '../types';
import { getDvpForMatchup, TeamDvp } from '../../dvp';

function clamp(val: number, min: number, max: number): number {
  return Math.max(min, Math.min(max, val));
}

function countTiers(dvp: TeamDvp | null): { easy: number; avg: number; tough: number; total: number } {
  if (!dvp || !dvp.ranks) return { easy: 0, avg: 0, tough: 0, total: 0 };
  let easy = 0, avg = 0, tough = 0;
  for (const r of dvp.ranks) {
    if (r.tier === 'EASY') easy++;
    else if (r.tier === 'TOUGH') tough++;
    else avg++;
  }
  return { easy, avg, tough, total: dvp.ranks.length };
}

function formatDvpCompact(dvp: TeamDvp | null): Record<string, Array<{ stat: string; rank: number; tier: string }>> | null {
  if (!dvp || !dvp.ranks) return null;
  const byPos: Record<string, Array<{ stat: string; rank: number; tier: string }>> = {};
  for (const r of dvp.ranks) {
    if (!byPos[r.position]) byPos[r.position] = [];
    byPos[r.position].push({ stat: r.stat, rank: r.rank, tier: r.tier });
  }
  return Object.keys(byPos).length > 0 ? byPos : null;
}

export const dvpSignal: Signal = {
  id: 'dvp',
  name: 'Defense vs Position Rankings',
  supportedLeagues: ['*'],

  async collect(ctx: MatchupContext): Promise<SignalResult> {
    const start = Date.now();
    try {
      const dvp = await getDvpForMatchup(ctx.homeTeam, ctx.awayTeam, ctx.league);
      const homeData = dvp.home;
      const awayData = dvp.away;

      const homeTiers = countTiers(homeData);
      const awayTiers = countTiers(awayData);

      const hasData = homeTiers.total > 0 || awayTiers.total > 0;

      // Score: proportion of EASY positions across both defenses
      // Higher = more exploitable defensive matchups available
      const totalPositions = homeTiers.total + awayTiers.total;
      const totalEasy = homeTiers.easy + awayTiers.easy;
      let score = 0.5;
      if (totalPositions > 0) {
        const easyRatio = totalEasy / totalPositions;
        // Map: 0% easy → 0.40, 33% → 0.55, 50% → 0.65, 100% → 0.85
        score = clamp(0.40 + easyRatio * 0.45, 0.35, 0.85);
      }

      return {
        signalId: 'dvp',
        score,
        weight: 0,
        available: hasData,
        rawData: {
          home: formatDvpCompact(homeData),
          away: formatDvpCompact(awayData),
          homeTiers,
          awayTiers,
        },
        metadata: {
          latencyMs: Date.now() - start,
          source: 'db',
          freshness: new Date().toISOString().slice(0, 10),
        },
      };
    } catch (err) {
      return {
        signalId: 'dvp', score: 0.5, weight: 0, available: false,
        rawData: { error: String(err) },
        metadata: { latencyMs: Date.now() - start, source: 'db', freshness: '' },
      };
    }
  },
};
