'use strict';

/**
 * deskShowcaseService (Truth-Everywhere Part 2, item 6) — REAL data for the
 * pricing-page Desk showcase. The ladder/Kelly/phi were hardcoded mocks; this
 * feeds the flagship demo from the pre-graded snapshot, or returns nothing so
 * the visuals HIDE (real-or-hidden, same law as the hero). No grading, no
 * credits — cache reads only.
 *
 *  - ladder: a real A/B graded prop's alt-line ladder (line + grade; the edge
 *    is shown only when it's a plausible market value, else omitted — the
 *    (model-line)/line metric is huge on 0.5-lines and would look fake).
 *  - parlay: the model's real same-team correlation (0.34, mirrors the frontend
 *    parlayMath team constant) computed for TWO REAL same-team A/B legs. No
 *    real pair on the board → null (hidden), never an invented number.
 *  - kelly: null — the snapshot carries no odds, so a real quarter-Kelly % can't
 *    be computed here. The tile hides rather than show a fabricated 2.4%.
 */

const DEFAULT_SPORTS = ['nba', 'wnba', 'mlb', 'soccer'];
const TEAM_CORRELATION = 0.34; // mirrors web parlayMath: same-team pairwise phi
const SANE_EDGE_MAX = 40;      // beyond this the (model-line)/line value isn't a market edge

const isAB = (g) => /^[AB]/.test(String(g || '').trim().toUpperCase());
const distinctGrades = (ladder) => new Set((ladder || []).map((r) => r.grade)).size;

function rungsOf(alt) {
  return (alt || [])
    .filter((r) => r && Number.isFinite(Number(r.line)) && r.grade)
    .map((r) => {
      const edge = Number(r.edge_pct);
      return {
        line: Number(r.line),
        grade: r.grade,
        base: !!r.base,
        // guard the small-line artifact: show an edge only when it's plausible
        edge: Number.isFinite(edge) && Math.abs(edge) <= SANE_EDGE_MAX ? Math.round(edge * 10) / 10 : null,
      };
    })
    .sort((a, b) => a.line - b.line);
}

async function getDeskShowcase(deps = {}) {
  const cacheGet = deps.cacheGet || require('../utils/redis').cacheGet;
  const sports = deps.sports || DEFAULT_SPORTS;

  const ab = [];
  for (const sport of sports) {
    let grades = null;
    const snap = await cacheGet(`snapshot:${sport}:latest`);
    if (snap && Array.isArray(snap.grades)) grades = snap.grades;
    else {
      const env = await cacheGet(`grades:${sport}`);
      if (env && Array.isArray(env.grades)) grades = env.grades;
    }
    for (const g of grades || []) {
      if (!g || g.insufficient_data || !isAB(g.grade)) continue;
      ab.push({ g, sport });
    }
  }

  // Ladder: prefer the prop whose ladder shows the MOST grade variation (the
  // most compelling REAL example — "A here, C there"), then longest ladder.
  let best = null, bestScore = -1;
  for (const { g, sport } of ab) {
    const rungs = rungsOf(g.alt_lines);
    if (rungs.length < 2) continue;
    const score = distinctGrades(rungs) * 100 + rungs.length;
    if (score > bestScore) { bestScore = score; best = { g, sport, rungs }; }
  }

  if (!best) return { available: false };

  const ladder = {
    player: best.g.player_name || best.g.player || null,
    stat_type: best.g.stat_type || best.g.stat || null,
    sport: best.sport,
    rungs: best.rungs,
  };

  // Parlay phi: two REAL A/B legs on the same (non-null) team.
  let parlay = null;
  const byTeam = {};
  for (const { g } of ab) {
    const t = g.team ? String(g.team) : null;
    const name = g.player_name || g.player;
    if (!t || !name) continue;
    (byTeam[t] = byTeam[t] || []).push(name);
  }
  for (const [team, names] of Object.entries(byTeam)) {
    const uniq = [...new Set(names)];
    if (uniq.length >= 2) { parlay = { value: TEAM_CORRELATION, legs: [uniq[0], uniq[1]], team }; break; }
  }

  return { available: true, ladder, parlay, kelly: null };
}

module.exports = { getDeskShowcase, __internals: { rungsOf, isAB, SANE_EDGE_MAX, TEAM_CORRELATION } };
