/**
 * Round-plan helpers shared by the championship form (client) and its server action. Pure: no
 * database, so the client bundle never pulls in Prisma.
 */
import { DEFAULT_TIMINGS, ROUND_RULES, type RoundKind } from '@pintrush/engine';
import { ROUND_KIND_LABELS } from '../format';

export interface PlanRowInput {
  kind: RoundKind;
  packKey: string;
  label: string;
}

export interface PlanItem extends PlanRowInput {
  segment: number;
}

export interface PackChoice {
  key: string;
  name: string;
  kind: 'GENERAL' | 'MUSIC';
  questionCount: number;
}

/** Music Mayhem uses a MUSIC pack by default; everything else a GENERAL pack. */
export function preferredPackKind(kind: RoundKind): 'GENERAL' | 'MUSIC' {
  return kind === 'MUSIC_MAYHEM' ? 'MUSIC' : 'GENERAL';
}

export function defaultPackFor(kind: RoundKind, packs: readonly PackChoice[]): string {
  const want = preferredPackKind(kind);
  const preferredKey = want === 'MUSIC' ? 'music-mayhem-v1' : 'originals-v1';
  return (
    packs.find((p) => p.key === preferredKey)?.key ??
    packs.find((p) => p.kind === want)?.key ??
    packs[0]?.key ??
    preferredKey
  );
}

/**
 * Segments follow the labels: consecutive rounds with the same label form one segment (they share
 * the shorter 20 s break), and a new label starts the next segment. This always satisfies the
 * "segments never decrease" rule in eventConfigSchema.
 */
export function withSegments(rows: readonly PlanRowInput[]): PlanItem[] {
  let segment = 0;
  return rows.map((row, i) => {
    if (i > 0 && row.label.trim() !== rows[i - 1]!.label.trim()) segment++;
    return { kind: row.kind, packKey: row.packKey, label: row.label.trim(), segment };
  });
}

/** Rough show length from the engine's default timings (intro, 10/5 questions, round-over, breaks). */
export function estimatePlanMinutes(rows: readonly PlanRowInput[]): number {
  const t = DEFAULT_TIMINGS;
  const items = withSegments(rows);
  let ms = 0;
  items.forEach((item, i) => {
    const rules = ROUND_RULES[item.kind];
    // Final Rush prefers DIFFICULT questions; board rounds end on the 20 s wildcard.
    const perQuestion = (window: number) => t.pendingMs + window + t.lockedMs + t.revealMs;
    const standard = item.kind === 'FINAL_RUSH' ? 0 : rules.questionCount - (rules.hasBoard ? 1 : 0);
    const long = rules.questionCount - standard;
    ms += t.introMs + standard * perQuestion(t.windowMs) + long * perQuestion(t.difficultWindowMs) + t.roundOverMs;
    if (i > 0) ms += item.segment === items[i - 1]!.segment ? 20_000 : 30_000;
  });
  return Math.round(ms / 60_000);
}

export function defaultLabel(kind: RoundKind): string {
  return ROUND_KIND_LABELS[kind];
}
