/**
 * RIE Signal: PIFF 3.0 (Player Prop Intelligence)
 *
 * Wraps the existing piff.ts loader. Computes a 0-1 confidence score from
 * PIFF prop edges using tanh mapping. Supports all leagues.
 *
 * Also absorbs DIGIMON's drop-line concept: when a player faces an EASY DVP
 * defense, the effective edge is boosted based on miss-pattern logic.
 */

import { Signal, SignalResult, MatchupContext } from '../types';
import { loadPiffPropsForDate, getPiffPropsForGame, PiffLeg } from '../../piff';
import { getCurrentEtDateKey, getEtDateKey } from '../../../lib/league-windows';

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

function getPiffMap(startsAt?: string): { date: string; data: Record<string, PiffLeg[]> } {
  const targetDate = getEtDateKey(startsAt || '') || getCurrentEtDateKey();
  if (piffCache && piffCache.date === targetDate) return piffCache;
  const data = loadPiffPropsForDate(targetDate);
  piffCache = { date: targetDate, data };
  return piffCache;
}

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

/**
 * Compute PIFF confidence score from prop edges.
 *
 * Uses tanh mapping: edge=0 → 0.50, edge=0.20 → 0.60, edge=0.40 → 0.70
 * Weighted by leg count: 1 leg = 70% confidence, 3+ = 100%
 *
 * Drop-line boost: legs against EASY defense (dvp_tier) with high H2H hit rates
 * get a 10% edge boost (absorbed from DIGIMON concept).
 */
function computePiffScore(props: PiffLeg[]): number {
  const validProps = props.filter(p => typeof p.edge === 'number' && !isNaN(p.edge));
  if (validProps.length === 0) return 0.5;

  // Apply drop-line boost for EASY DVP matchups
  const boostedProps = validProps.map(p => {
    let effectiveEdge = p.edge;
    // DIGIMON absorption: EASY defense + strong H2H = boost edge
    if (p.dvp_tier === 'EASY' || p.dvp_tier === 'ELITE') {
      if (p.h2h_hr && p.h2h_hr >= 0.70 && p.h2h_games && p.h2h_games >= 3) {
        effectiveEdge *= 1.10; // 10% boost
      } else if (p.dvp_rank && p.dvp_rank <= 5) {
        effectiveEdge *= 1.05; // 5% boost for top-5 defense weakness
      }
    }
    return effectiveEdge;
  });

  const avgEdge = boostedProps.reduce((sum, e) => sum + e, 0) / boostedProps.length;
  const baseScore = 0.5 + 0.45 * Math.tanh(avgEdge * 1.8);

  // Leg count confidence: 1 leg = 70%, 2 = 85%, 3+ = 100%
  const legConfidence = clamp(0.7 + (validProps.length - 1) * 0.15, 0.7, 1.0);
  return 0.5 + (baseScore - 0.5) * legConfidence;
}

export const piffSignal: Signal = {
  id: 'piff',
  name: 'PIFF 3.0 Player Props',
  // PIFF supports all leagues EXCEPT ncaab (confirmed by existing code)
  supportedLeagues: ['nba', 'nhl', 'mlb', 'epl', 'la_liga', 'bundesliga', 'serie_a', 'ligue_1', 'champions_league'],

  async collect(ctx: MatchupContext): Promise<SignalResult> {
    const start = Date.now();
    try {
      const { date: targetDate, data: piffMap } = getPiffMap(ctx.startsAt);
      const props = getPiffPropsForGame(ctx.homeShort, ctx.awayShort, piffMap, ctx.league);
      const score = computePiffScore(props);

      // Build raw data for audit
      const topPicks = props
        .sort((a, b) => b.edge - a.edge)
        .slice(0, 5)
        .map(p => ({
          name: p.name, stat: p.stat, line: p.line,
          edge: Math.round(p.edge * 1000) / 10,
          direction: p.direction || 'over',
          tier: p.tier_label || 'T3_SOLID',
          dvp_tier: p.dvp_tier,
          h2h_hr: p.h2h_hr,
          szn_hr: p.szn_hr,
        }));

      return {
        signalId: 'piff',
        score,
        weight: 0, // set by strategy
        available: props.length > 0,
        rawData: {
          legCount: props.length,
          avgEdge: props.length > 0
            ? Math.round(props.reduce((s, p) => s + p.edge, 0) / props.length * 1000) / 10
            : 0,
          topPicks,
        },
        metadata: {
          latencyMs: Date.now() - start,
          source: 'file',
          freshness: targetDate,
        },
      };
    } catch (err) {
      return {
        signalId: 'piff', score: 0.5, weight: 0, available: false,
        rawData: { error: String(err) },
        metadata: { latencyMs: Date.now() - start, source: 'file', freshness: '' },
      };
    }
  },
};
