/**
 * RIE Signal: DIGIMON v1.8 (DVP Miss Pattern)
 *
 * Wraps existing digimon.ts loader. NBA-only.
 * Score = inverse of average miss rate for actionable picks.
 *
 * Eventually vestigial once PIFF fully absorbs the drop-line concept.
 */

import { Signal, SignalResult, MatchupContext } from '../types';
import { loadDigimonPicksForDate, getDigimonForGame, DigimonPick } from '../../digimon';
import { getCurrentEtDateKey, getEtDateKey } from '../../../lib/league-windows';

let digimonCache: { date: string; data: Record<string, DigimonPick[]> } | null = null;

function getDigimonMap(startsAt?: string): { date: string; data: Record<string, DigimonPick[]> } {
  const targetDate = getEtDateKey(startsAt || '') || getCurrentEtDateKey();
  if (digimonCache && digimonCache.date === targetDate) return digimonCache;
  const data = loadDigimonPicksForDate(targetDate);
  digimonCache = { date: targetDate, data };
  return digimonCache;
}

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

export const digimonSignal: Signal = {
  id: 'digimon',
  name: 'DIGIMON DVP Miss Pattern',
  supportedLeagues: ['nba'],

  async collect(ctx: MatchupContext): Promise<SignalResult> {
    const start = Date.now();
    try {
      const { date: targetDate, data: digiMap } = getDigimonMap(ctx.startsAt);
      const picks = getDigimonForGame(ctx.homeShort, ctx.awayShort, digiMap);
      const actionable = picks.filter(p => p.verdict !== 'SKIP');

      let score = 0.5;
      if (actionable.length > 0) {
        const avgMissRate = actionable.reduce((s, p) => s + p.missRate, 0) / actionable.length;
        score = clamp(1 - avgMissRate, 0, 1);
      }

      const topPicks = picks
        .filter(p => p.verdict === 'LOCK' || p.verdict === 'PLAY')
        .slice(0, 5)
        .map(p => ({
          player: p.player, prop: p.prop, line: p.line,
          missRate: p.missRate, verdict: p.verdict, dvpTier: p.dvpTier,
        }));

      return {
        signalId: 'digimon',
        score,
        weight: 0,
        available: actionable.length > 0,
        rawData: {
          pickCount: picks.length,
          actionableCount: actionable.length,
          lockCount: picks.filter(p => p.verdict === 'LOCK').length,
          avgMissRate: actionable.length > 0
            ? Math.round(actionable.reduce((s, p) => s + p.missRate, 0) / actionable.length * 100) / 100
            : null,
          topPicks,
        },
        metadata: {
          latencyMs: Date.now() - start,
          source: 'file',
          freshness: targetDate,
        },
      };
    } catch (err) {
      return {
        signalId: 'digimon', score: 0.5, weight: 0, available: false,
        rawData: { error: String(err) },
        metadata: { latencyMs: Date.now() - start, source: 'file', freshness: '' },
      };
    }
  },
};
