/**
 * Text Variation System
 *
 * Utility functions for making repeated game events feel fresh by
 * providing multiple text variants, template replacement, and
 * contextual labeling based on player state.
 */

import type { Player } from '../models/Player.js';

/**
 * Pick a random variant from an array of strings.
 * Optionally accepts a seed string for deterministic selection
 * (uses simple hash so the same seed always picks the same variant).
 */
export function pickVariant(variants: string[], seed?: string): string {
  if (variants.length === 0) return '';
  if (variants.length === 1) return variants[0];

  if (seed !== undefined) {
    let hash = 0;
    for (let i = 0; i < seed.length; i++) {
      hash = ((hash << 5) - hash + seed.charCodeAt(i)) | 0;
    }
    const index = Math.abs(hash) % variants.length;
    return variants[index];
  }

  return variants[Math.floor(Math.random() * variants.length)];
}

/**
 * Replace `{variable}` placeholders in a template string with values
 * from the provided context object.
 *
 * @example
 * templateReplace('{name} feels {mood} this {timeOfDay}', { name: 'Alex', mood: 'happy', timeOfDay: 'morning' })
 * // => 'Alex feels happy this morning'
 */
export function templateReplace(
  text: string,
  context: Record<string, string | number>
): string {
  return text.replace(/\{(\w+)\}/g, (_match, key: string) => {
    const value = context[key];
    return value !== undefined ? String(value) : `{${key}}`;
  });
}

/**
 * Convert an hour (0-23) into a human-readable time-of-day label.
 */
export function getTimeOfDayLabel(hour: number): string {
  if (hour >= 5 && hour < 12) return 'morning';
  if (hour >= 12 && hour < 17) return 'afternoon';
  if (hour >= 17 && hour < 21) return 'evening';
  return 'night';
}

/**
 * Return a short descriptive adjective for a weather type.
 */
export function getWeatherAdjective(weather: string): string {
  const map: Record<string, string> = {
    sunny: 'bright and sunny',
    cloudy: 'overcast',
    rainy: 'rainy',
    snowy: 'snowy',
    stormy: 'stormy',
    windy: 'breezy',
    foggy: 'misty',
  };
  return map[weather] ?? 'mild';
}

/**
 * Build a template-replacement context from the current player state.
 * The returned record can be fed straight into `templateReplace`.
 */
export function buildEventContext(player: Player): Record<string, string> {
  const c = player.c;
  return {
    name: c.firstname ?? 'you',
    timeOfDay: getTimeOfDayLabel(player.hourOfDay ?? 0),
    weather: getWeatherAdjective((player as any).weather ?? ''),
    season: player.season ?? 'spring',
    weekDay: (player as any).weekDayText ?? 'today',
    age: String(c.ageYears ?? 0),
    occupation: c.occupation ?? '',
  };
}
