import type { Rng } from '@/lib/rng';
import { createRng } from '@/lib/rng';
import { rollDice } from '@/lib/dice/notation';

/** The classic 5e/PF2e-ish standard array. */
export const STANDARD_ARRAY = [15, 14, 13, 12, 10, 8] as const;

/** Roll six ability scores as 4d6, drop the lowest. */
export function rollAbilityScores(rng: Rng = createRng()): number[] {
  return Array.from({ length: 6 }, () => rollDice('4d6kh3', rng).total);
}

/**
 * Point-buy (27-point standard). Scores 8–15; costs 0,1,2,3,4,5,7,9 for 8..15.
 * Returns the cost of a single score, or null if out of the buyable range.
 */
const POINT_COST: Record<number, number> = { 8: 0, 9: 1, 10: 2, 11: 3, 12: 4, 13: 5, 14: 7, 15: 9 };
export const POINT_BUY_BUDGET = 27;
export const POINT_BUY_MIN = 8;
export const POINT_BUY_MAX = 15;

export function pointCost(score: number): number | null {
  return score in POINT_COST ? POINT_COST[score]! : null;
}

/** Total points spent across six scores (Infinity if any score is out of range). */
export function pointBuySpent(scores: number[]): number {
  let total = 0;
  for (const s of scores) {
    const c = pointCost(s);
    if (c === null) return Infinity;
    total += c;
  }
  return total;
}

export function pointBuyRemaining(scores: number[]): number {
  return POINT_BUY_BUDGET - pointBuySpent(scores);
}
