/**
 * Relevance decay for palace memories.
 *
 * Uses exponential half-life decay: relevance halves every N days.
 * Memories that are accessed/referenced get their relevance boosted.
 */

const MS_PER_DAY = 86_400_000;

/**
 * Compute decayed relevance using exponential half-life.
 *
 * @param originalRelevance - Initial relevance score (0-1)
 * @param createdAt - ISO date string or Date when the memory was created/last accessed
 * @param halfLifeDays - Number of days for relevance to halve (default: 30)
 * @param asOf - Reference time for decay calculation (default: now)
 * @returns Decayed relevance score (0-1)
 */
export function computeDecayedRelevance(
  originalRelevance: number,
  createdAt: string | Date,
  halfLifeDays = 30,
  asOf: Date = new Date()
): number {
  if (halfLifeDays <= 0) return originalRelevance;
  if (originalRelevance <= 0) return 0;

  const created = typeof createdAt === 'string' ? new Date(createdAt) : createdAt;
  const elapsedMs = asOf.getTime() - created.getTime();

  if (elapsedMs <= 0) return Math.min(originalRelevance, 1);

  const elapsedDays = elapsedMs / MS_PER_DAY;
  const decayFactor = Math.pow(0.5, elapsedDays / halfLifeDays);

  return Math.max(0, Math.min(1, originalRelevance * decayFactor));
}

/**
 * Compute a boosted relevance for a memory that was accessed/referenced.
 *
 * Boost formula: new = old + (1 - old) * boostFactor
 * This asymptotically approaches 1.0 without exceeding it.
 *
 * @param currentRelevance - Current relevance score (0-1)
 * @param boostFactor - How much of the remaining gap to close (default: 0.3)
 * @returns Boosted relevance score (0-1)
 */
export function boostRelevance(currentRelevance: number, boostFactor = 0.3): number {
  const boosted = currentRelevance + (1 - currentRelevance) * boostFactor;
  return Math.min(1, Math.max(0, boosted));
}
