/**
 * clvDisplay (DS4 · Billboards — CLV reframe, DESIGN-SPEC Part 3 #16).
 *
 * "Charts that are flat should SAY so." When settled CLV is near-flat (e.g.
 * 73 of 74 reads landed at the close), a 7-bar histogram is one giant bar and
 * six empty stubs — it reads as BROKEN. The record (55-19, 74% hit) is the
 * best data on the site; it must look the MOST premium, never errored.
 *
 * This is the single pure decision: given the server's `clv_distribution`
 * (already n≥20 gated in ledgerService), decide FLAT vs SPREAD. Flat → a
 * confident VOICE line. Spread → the real bars. Pure + CommonJS so the .tsx
 * consumers (ledger, profile) and Jest share one tested rule.
 */

// The flat bucket must hold this share of settled CLV for the histogram to be
// declared "flat." 73/74 → 0.986; a genuinely dispersed book → well under.
const FLAT_SHARE_THRESHOLD = 0.6;

// VOICE-compliant one-liner. No jargon; states the model's actual claim.
const CLV_FLAT_LINE = 'CLV flat — we grade the outcome, not the close.';

/**
 * @param {Array<{label:string,count:number,side:'beat'|'faded'|'flat'}>|null} dist
 * @returns {{ mode:'flat'|'spread'|'none', total:number, flat:number, flatShare:number }}
 */
function clvMode(dist) {
  if (!Array.isArray(dist) || dist.length === 0) {
    return { mode: 'none', total: 0, flat: 0, flatShare: 0 };
  }
  const total = dist.reduce((n, b) => n + (Number(b && b.count) || 0), 0);
  if (total <= 0) return { mode: 'none', total: 0, flat: 0, flatShare: 0 };
  const flat = dist
    .filter((b) => b && b.side === 'flat')
    .reduce((n, b) => n + (Number(b.count) || 0), 0);
  const flatShare = flat / total;
  const mode = flatShare >= FLAT_SHARE_THRESHOLD ? 'flat' : 'spread';
  return { mode, total, flat, flatShare };
}

/** Convenience predicate for the flat branch. */
function isFlatClv(dist) {
  return clvMode(dist).mode === 'flat';
}

module.exports = { clvMode, isFlatClv, CLV_FLAT_LINE, FLAT_SHARE_THRESHOLD };
