const fs = require('fs');
const path = require('path');

const ROOT = path.resolve(__dirname, '..');
const OUT_DIR = path.join(ROOT, 'docs', 'generated-formula-libraries', 'physics');

const BRANCHES = [
  'analytical-mechanics',
  'lagrangian-mechanics',
  'hamiltonian-mechanics',
  'symplectic-mechanics',
  'rigid-body-rotation',
  'continuum-mechanics',
  'elasticity-and-fracture',
  'nonlinear-oscillators',
  'wave-mechanics',
  'acoustics-and-resonance',
  'geometric-optics',
  'wave-optics',
  'electromagnetic-field-theory',
  'maxwell-systems',
  'circuit-fields',
  'plasma-physics',
  'special-relativity',
  'general-relativity',
  'quantum-mechanics',
  'quantum-operators',
  'quantum-field-lattice',
  'statistical-mechanics',
  'thermodynamics',
  'fluid-dynamics',
  'navier-stokes-systems',
  'turbulence',
  'solid-state-physics',
  'crystal-lattice',
  'semiconductor-physics',
  'particle-physics',
  'gauge-fields',
  'cosmology',
  'astrophysics',
  'chaos-in-physics',
  'multiscale-physics',
];

const FAMILIES = [
  ['linear_motion', 'linear motion', 2, 4, 'B=A+velocity*time+bias mod N'],
  ['projectile_curve', 'projectile curve', 3, 5, 'B=(x+vx*t, y+vy*t-g*t*t) mod N'],
  ['oscillator_phase', 'oscillator phase', 4, 7, 'B=A+table(phase, wave_table) mod N'],
  ['energy_shell', 'energy shell', 5, 8, 'B=A+bucket(kinetic+potential) mod N'],
  ['lagrangian_gate', 'Lagrangian gate', 6, 9, 'B=branch(L=T-V)'],
  ['hamiltonian_flow', 'Hamiltonian flow', 7, 10, 'B=(x+dHdp, y-dHdx) mod N'],
  ['symplectic_step', 'symplectic step', 7, 10, 'B=symplectic_update(A,p) mod N'],
  ['rigid_rotation', 'rigid rotation', 4, 7, 'B=R(theta)*A+bias mod N'],
  ['elastic_strain', 'elastic strain', 5, 8, 'B=A+strain_tensor(A)*direction mod N'],
  ['fracture_threshold', 'fracture threshold', 5, 9, 'B=branch(stress(A)>threshold)'],
  ['wave_interference', 'wave interference', 5, 9, 'B=A+wave1(phase)+wave2(phase) mod N'],
  ['resonance_bucket', 'resonance bucket', 4, 8, 'B=A+bucket(frequency/period) mod N'],
  ['ray_refraction', 'ray refraction', 3, 6, 'B=Snell_like_transform(A) mod N'],
  ['diffraction_pattern', 'diffraction pattern', 6, 10, 'B=A+fringe_bucket(A) mod N'],
  ['maxwell_flux', 'Maxwell flux', 7, 10, 'B=A+divE+curlB mod N'],
  ['circuit_filter', 'circuit filter', 4, 8, 'B=A+filter_response(A) mod N'],
  ['relativistic_factor', 'relativistic factor', 6, 9, 'B=A+bucket(gamma(v)) mod N'],
  ['metric_curvature', 'metric curvature', 8, 10, 'B=A+curvature(metric,A) mod N'],
  ['quantum_phase', 'quantum phase', 7, 10, 'B=A+phase_bucket(psi) mod N'],
  ['operator_commutator', 'operator commutator', 8, 10, 'B=A+bucket([A,B]) mod N'],
  ['lattice_gauge', 'lattice gauge', 8, 10, 'B=A+plaquette_phase mod N'],
  ['boltzmann_bucket', 'Boltzmann bucket', 6, 10, 'B=A+table(energy,temp_table) mod N'],
  ['entropy_gradient', 'entropy gradient', 6, 9, 'B=A+gradient(entropy) mod N'],
  ['navier_stokes_step', 'Navier-Stokes step', 8, 10, 'B=A+velocity-advect+diffuse-pressure mod N'],
  ['turbulence_seed', 'turbulence seed', 8, 10, 'B=A+nonlinear_vortex_bucket(A) mod N'],
  ['crystal_lattice', 'crystal lattice', 5, 9, 'B=A+lattice_basis(index(A)) mod N'],
  ['band_structure', 'band structure', 7, 10, 'B=A+bucket(dispersion(k)) mod N'],
  ['particle_scatter', 'particle scatter', 7, 10, 'B=A+scattering_angle_bucket(A) mod N'],
  ['cosmic_redshift', 'cosmic redshift', 5, 8, 'B=A+bucket(scale_factor(time)) mod N'],
  ['orbital_resonance', 'orbital resonance', 5, 9, 'B=A+orbit_phase_bucket(A) mod N'],
];

function titleCase(value) {
  return value
    .split('-')
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(' ');
}

function writeBranch(branch, index) {
  const rows = FAMILIES.map(([id, label, min, max, prototype]) => {
    const familyId = `physics.${branch}.${id}`;
    const boss = max >= 9 ? 'yes' : 'component';
    return `| ${familyId} | ${label} | ${min}-${max} | ${titleCase(branch)} | ${boss} | \`${prototype}\` |`;
  });

  const body = [
    `# Physics Extension ${String(index + 1).padStart(2, '0')} ${titleCase(branch)}`,
    '',
    '## Purpose',
    '',
    'This file defines executable formula families for the mazexchain physics library.',
    '',
    '## Formula Families',
    '',
    '| Family ID | Subclass | Difficulty | Theme Scope | Boss | Prototype |',
    '|---|---|---|---|---|---|',
    ...rows,
    '',
    '## Integration Rule',
    '',
    'Each row is intended to be materialized into a directly allocatable, executable, and verifiable formula asset.',
    '',
  ].join('\n');

  fs.writeFileSync(path.join(OUT_DIR, `${String(index + 1).padStart(2, '0')}_${branch}.md`), body, 'utf8');
}

function main() {
  fs.mkdirSync(OUT_DIR, { recursive: true });
  BRANCHES.forEach(writeBranch);

  const index = [
    '# Physics Extension Formula Library',
    '',
    `Branches: ${BRANCHES.length}`,
    `Formula families per branch: ${FAMILIES.length}`,
    `Total candidate families: ${BRANCHES.length * FAMILIES.length}`,
    '',
    '| No. | Branch | File |',
    '|---:|---|---|',
    ...BRANCHES.map((branch, i) => `| ${i + 1} | ${titleCase(branch)} | ${String(i + 1).padStart(2, '0')}_${branch}.md |`),
    '',
  ].join('\n');

  fs.writeFileSync(path.join(OUT_DIR, 'README.md'), index, 'utf8');
  console.log(JSON.stringify({ output: OUT_DIR, branches: BRANCHES.length, families: FAMILIES.length }, null, 2));
}

main();
