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

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

const BRANCHES = [
  'basic-algebra',
  'advanced-algebra',
  'linear-algebra',
  'abstract-algebra',
  'number-theory',
  'combinatorics',
  'graph-theory',
  'discrete-mathematics',
  'calculus',
  'multivariable-calculus',
  'real-analysis',
  'complex-analysis',
  'functional-analysis',
  'ordinary-differential-equations',
  'partial-differential-equations',
  'dynamical-systems',
  'chaos',
  'topology',
  'differential-geometry',
  'tensor-geometry',
  'probability-theory',
  'stochastic-processes',
  'mathematical-statistics',
  'information-theory',
  'optimization-theory',
  'game-theory',
  'computational-mathematics',
  'numerical-analysis',
  'fourier-analysis',
  'wavelet-analysis',
  'fractals',
  'logic-and-set-theory',
  'category-theory',
];

const FAMILIES = [
  ['linear_offset', 'linear offset', 1, 3, 'u=(x+c) mod N; v=(y+f) mod N'],
  ['affine_mix', 'affine coordinate mix', 2, 4, 'u=(a*x+b*y+c) mod N; v=(d*x+e*y+f) mod N'],
  ['quadratic_surface', 'quadratic surface', 3, 6, 'u=(a*x*x+b*y+c) mod N; v=(d*y*y+e*x+f) mod N'],
  ['cross_term', 'cross term', 4, 6, 'u=(a*x+b*y+c*x*y+s) mod N; v=(d*y+e*x+f*x*y+t) mod N'],
  ['residue_gate', 'residue gate', 4, 7, 'u=if((x+y) mod p == r, formulaA, formulaB)'],
  ['prime_residue', 'prime residue', 5, 8, 'u=(x+a*(y mod p)+c) mod N; v=(y+b*(x mod q)+f) mod N'],
  ['crt_lock', 'Chinese remainder lock', 6, 9, 'z=CRT(x mod p, y mod q); B=(z, z+mix) mod N'],
  ['matrix_transform', 'matrix transform', 3, 6, 'B=M*A+bias mod N'],
  ['orthogonal_action', 'orthogonal action', 4, 7, 'B=R(theta)*A+bias mod N'],
  ['group_orbit', 'group orbit action', 6, 9, 'B=group_action(g,A)+orbit_bias mod N'],
  ['permutation_action', 'permutation action', 5, 8, 'B=permutation[index(A)] mod N'],
  ['graph_laplacian', 'graph Laplacian', 6, 9, 'B=A+L(A)+bias mod N'],
  ['combinatorial_rank', 'combinatorial rank', 5, 8, 'B=rank(combination(A))+bias mod N'],
  ['set_partition', 'set partition', 4, 7, 'B=if(A in partition_i, formula_i, formula_j)'],
  ['derivative_step', 'derivative step', 4, 7, 'B=A+gradient(F)(A) mod N'],
  ['integral_bucket', 'integral bucket', 4, 7, 'B=A+floor(accumulated_sum/scale) mod N'],
  ['jacobian_gate', 'Jacobian determinant gate', 5, 8, 'B=A+det(J_F(A))*direction mod N'],
  ['ode_flow', 'ODE flow step', 5, 8, 'A1=A+h*f(A); B=A1 mod N'],
  ['pde_kernel', 'PDE local kernel', 7, 10, 'B=A+laplace(F,A)+bias mod N'],
  ['fixed_point', 'fixed point iteration', 5, 8, 'B=F_k(A) mod N'],
  ['logistic_chaos', 'logistic chaos', 6, 10, 'z_next=r*z*(m-z); B=project(z_next)'],
  ['topology_invariant', 'topology invariant', 6, 9, 'B=A+invariant(component,cycle_rank) mod N'],
  ['curvature_map', 'curvature map', 7, 10, 'B=A+curvature(metric,A)*direction mod N'],
  ['tensor_contraction', 'tensor contraction', 8, 10, 'B=contract(T(A),basis) mod N'],
  ['probability_kernel', 'probability kernel', 4, 8, 'B=A+bucket(P(A))*direction mod N'],
  ['markov_projection', 'Markov projection', 6, 9, 'state_next=P(state); B=project(state_next)'],
  ['estimator_map', 'statistical estimator map', 4, 7, 'B=estimator(samples(A))+bias mod N'],
  ['entropy_gate', 'entropy gate', 5, 9, 'B=A+bucket(entropy(A))*direction mod N'],
  ['argmin_gate', 'argmin gate', 5, 9, 'B=branch(argmin(cost_i(A)))'],
  ['payoff_equilibrium', 'payoff equilibrium', 5, 9, 'B=branch(payoff(A)>=threshold)'],
  ['fourier_phase', 'Fourier phase map', 6, 10, 'B=A+harmonic_bucket(k*x+w*y+phase) mod N'],
  ['wavelet_bucket', 'wavelet bucket', 6, 10, 'B=A+wavelet_scale_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 = `math.${branch}.${id}`;
    const boss = max >= 9 ? 'yes' : 'component';
    return `| ${familyId} | ${label} | ${min}-${max} | ${titleCase(branch)} | ${boss} | \`${prototype}\` |`;
  });

  const body = [
    `# Mathematics Extension ${String(index + 1).padStart(2, '0')} ${titleCase(branch)}`,
    '',
    '## Purpose',
    '',
    'This file defines executable formula families for the mazexchain mathematics 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 = [
    '# Mathematics 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();
