// Pure helpers for the nightly in-tournament Team-DC refit (no fs/db imports, // so vitest can load them). The training base comes from dcTrain.json — compact // [date, home, away, hs, as, neutral01] rows with absolute dates — plus every // finished World Cup fixture so far. import { hostAdvantage } from '../../src/lib/model/hosts'; import type { DcMatch } from '../../src/lib/model/teamDc'; import type { Fixture } from '../../src/lib/types'; export type DcRow = [string, string, string, number, number, number]; const DAY = 24 * 60 * 60 * 1000; /** Build the refit training set, with daysAgo relative to the newest match in * the combined data. Host-nation fixtures are oriented so the host is the * DC home side (the CSV convention for non-neutral rows). */ export function refitTrainingSet( base: { asOf: string; rows: DcRow[] }, finished: Fixture[], homeAdvElo: number, windowYears = 15, ): { train: DcMatch[]; asOf: string } { let asOf = base.asOf; const extra: { date: string; home: string; away: string; hs: number; as: number; neutral: boolean }[] = []; for (const f of finished) { if (!f.home.team || !f.away.team || f.homeScore == null || f.awayScore == null) continue; const date = f.kickoff.slice(0, 10); if (date > asOf) asOf = date; const adv = hostAdvantage(f.home.team, f.away.team, f.venue, homeAdvElo); if (adv < 0) { extra.push({ date, home: f.away.team, away: f.home.team, hs: f.awayScore, as: f.homeScore, neutral: false }); } else { extra.push({ date, home: f.home.team, away: f.away.team, hs: f.homeScore, as: f.awayScore, neutral: adv === 0 }); } } const nowT = new Date(asOf).getTime(); const windowMs = windowYears * 365 * DAY; const train: DcMatch[] = []; for (const [date, home, away, hs, as, neutral] of base.rows) { const t = new Date(date).getTime(); if (nowT - t > windowMs) continue; train.push({ daysAgo: (nowT - t) / DAY, home, away, homeGoals: hs, awayGoals: as, neutral: neutral === 1 }); } for (const m of extra) { train.push({ daysAgo: (nowT - new Date(m.date).getTime()) / DAY, home: m.home, away: m.away, homeGoals: m.hs, awayGoals: m.as, neutral: m.neutral, }); } return { train, asOf }; }