/**
 * Composer record generator.
 *
 * Produces Composer records linked to existing Work IDs, with names,
 * associated work counts, and 24-month income history.
 */

import type { SeededRng } from '@/lib/mock-data/seed';
import type { Composer, Work } from '@/lib/mock-data/types';

const FIRST_NAMES = [
  'Carlos', 'María', 'James', 'Yuki', 'Sofia',
  'André', 'Liam', 'Priya', 'Chen', 'Fatima',
  'Lucas', 'Emma', 'Diego', 'Aisha', 'Oliver',
  'Valentina', 'Noah', 'Sakura', 'Mateo', 'Ingrid',
  'Rafael', 'Chloe', 'Hassan', 'Mei', 'Gabriel',
] as const;

const LAST_NAMES = [
  'García', 'Müller', 'Tanaka', 'Smith', 'Silva',
  'Johansson', 'Kim', 'Patel', 'Dubois', 'Rossi',
  'Hernández', 'Nakamura', 'Williams', 'López', 'Chen',
  'Andersson', 'Nguyen', 'Brown', 'Martínez', 'Sato',
  'Fischer', 'Santos', 'Ali', 'Moreau', 'Costa',
] as const;

/**
 * Generate 24 months of income data (Jan 2024 – Dec 2025).
 */
function generateMonthlyIncome(rng: SeededRng): Array<{ month: string; amount: number }> {
  const months: Array<{ month: string; amount: number }> = [];
  const baseIncome = rng.randomFloat(200, 8000);

  for (let year = 2024; year <= 2025; year++) {
    for (let m = 1; m <= 12; m++) {
      const month = `${year}-${String(m).padStart(2, '0')}`;
      const variation = rng.randomFloat(0.4, 1.6);
      const amount = Math.round(baseIncome * variation * 100) / 100;
      months.push({ month, amount });
    }
  }

  return months;
}

/**
 * Generate Composer records linked to existing Works.
 *
 * @param rng   - Seeded PRNG instance
 * @param count - Number of composers to generate (≥50 recommended)
 * @param works - Previously generated Work records to link against
 */
export function generateComposers(rng: SeededRng, count: number, works: Work[]): Composer[] {
  const composers: Composer[] = [];
  const startDate = new Date('2024-01-01');
  const endDate = new Date('2025-12-31');

  // Build a map of composerId → workIds from the works' writerSplits
  const composerWorkMap = new Map<string, string[]>();
  for (const work of works) {
    for (const split of work.writerSplits) {
      const existing = composerWorkMap.get(split.composerId) ?? [];
      existing.push(work.id);
      composerWorkMap.set(split.composerId, existing);
    }
  }

  for (let i = 0; i < count; i++) {
    const id = `CMP-${String(i + 1).padStart(4, '0')}`;
    const firstName = rng.pick(FIRST_NAMES);
    const lastName = rng.pick(LAST_NAMES);

    // Use works already linked via writerSplits, or assign random works
    let associatedWorkIds = composerWorkMap.get(id) ?? [];
    if (associatedWorkIds.length === 0) {
      const workCount = rng.randomInt(1, 8);
      const shuffled = rng.shuffle(works);
      associatedWorkIds = shuffled.slice(0, workCount).map((w) => w.id);
    }

    composers.push({
      id,
      name: `${firstName} ${lastName}`,
      workCount: associatedWorkIds.length,
      associatedWorkIds,
      monthlyIncome: generateMonthlyIncome(rng),
      createdAt: rng.randomDate(startDate, endDate),
    });
  }

  return composers;
}
