#!/usr/bin/env node
/**
 * Mathematical Techniques Seeding for RuVector
 *
 * Seeds the RuVector database with competition math technique hints and formulas
 * that T1 models can retrieve when solving problems.
 *
 * Architecture:
 * - Each technique is stored with natural language description, LaTeX formula, and usage hints
 * - Embeddings enable semantic matching (e.g., "sum of squares" -> formula retrieval)
 * - Step-by-step application hints guide T1 model decomposition
 *
 * Usage:
 *   npx tsx scripts/seed-math-techniques.ts
 *
 * Requirements:
 *   - OPENAI_API_KEY or ZAI_API_KEY environment variable
 *   - RuVector database initialized
 */

import { execSync } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';

// ============================================================================
// Mathematical Technique Database
// ============================================================================

interface MathTechnique {
  id: string;
  name: string;
  category: string;
  difficulty: number; // 0.0-1.0
  formula?: string; // LaTeX
  description: string;
  whenToUse: string[];
  stepByStepHints: string[];
  examples: string[];
  commonMistakes: string[];
  relatedTechniques: string[];
}

const MATH_TECHNIQUES: MathTechnique[] = [
  // ===== ALGEBRAIC SERIES & SUMMATION FORMULAS =====
  {
    id: 'sum-of-squares',
    name: 'Sum of Squares Formula',
    category: 'algebraic-series',
    difficulty: 0.3,
    formula: '\\sum_{k=1}^{n} k^2 = \\frac{n(n+1)(2n+1)}{6}',
    description: 'Direct formula for computing the sum of the first n perfect squares',
    whenToUse: [
      'Problem asks for sum of consecutive squares',
      'Series involves k² terms',
      'Counting problems with quadratic growth',
      'Optimization problems with square terms',
    ],
    stepByStepHints: [
      'Step 1: Identify that you need sum of k² from k=1 to k=n',
      'Step 2: Apply formula: n(n+1)(2n+1)/6',
      'Step 3: Simplify by computing n(n+1) first, then multiply by (2n+1)',
      'Step 4: Divide final result by 6',
      'Step 5: Verify with small case (e.g., n=3: 1+4+9=14, formula gives 3*4*7/6=14)',
    ],
    examples: [
      'Find 1² + 2² + 3² + ... + 100² = 100(101)(201)/6 = 338,350',
      'Sum of squares from 1 to n equals n(n+1)(2n+1)/6',
      'For n=10: 10*11*21/6 = 385',
    ],
    commonMistakes: [
      'Confusing with sum of cubes formula',
      'Forgetting to divide by 6',
      'Using (n²(n+1)²)/4 instead (that is sum of cubes)',
      'Not simplifying n(n+1)(2n+1) before dividing',
    ],
    relatedTechniques: ['sum-of-cubes', 'arithmetic-series', 'telescoping-series'],
  },
  {
    id: 'sum-of-cubes',
    name: 'Sum of Cubes Formula',
    category: 'algebraic-series',
    difficulty: 0.3,
    formula: '\\sum_{k=1}^{n} k^3 = \\left[\\frac{n(n+1)}{2}\\right]^2',
    description: 'Direct formula showing sum of cubes equals square of arithmetic series sum',
    whenToUse: [
      'Problem asks for sum of consecutive cubes',
      'Series involves k³ terms',
      'Pattern recognition: sum of cubes = (sum of numbers)²',
    ],
    stepByStepHints: [
      'Step 1: Recognize sum of k³ from k=1 to k=n',
      'Step 2: Compute arithmetic series sum: n(n+1)/2',
      'Step 3: Square the result from step 2',
      'Step 4: Verify: 1³+2³+3³ = (1+2+3)² = 6² = 36',
    ],
    examples: [
      'Find 1³ + 2³ + 3³ + ... + 10³ = (10*11/2)² = 55² = 3,025',
      'Sum from 1 to n cubed = [n(n+1)/2]²',
      'For n=5: (5*6/2)² = 15² = 225',
    ],
    commonMistakes: [
      'Confusing with sum of squares formula',
      'Forgetting to square the arithmetic sum',
      'Computing n²(n+1)²/4 incorrectly',
    ],
    relatedTechniques: ['sum-of-squares', 'arithmetic-series', 'algebraic-identities'],
  },
  {
    id: 'arithmetic-series',
    name: 'Arithmetic Series Sum',
    category: 'algebraic-series',
    difficulty: 0.2,
    formula: '\\sum_{k=1}^{n} (a + (k-1)d) = \\frac{n(a_1 + a_n)}{2} = \\frac{n(2a + (n-1)d)}{2}',
    description: 'Sum of arithmetic sequence: average of first and last term, times number of terms',
    whenToUse: [
      'Sequence has constant difference between consecutive terms',
      'Linear growth pattern',
      'Evenly spaced values',
    ],
    stepByStepHints: [
      'Step 1: Identify first term (a), last term (aₙ), and number of terms (n)',
      'Step 2: Apply formula: sum = n(a₁ + aₙ)/2',
      'Step 3: Alternative: if you know common difference d, use n(2a + (n-1)d)/2',
      'Step 4: Verify with small example',
    ],
    examples: [
      'Sum 1+2+3+...+100 = 100(1+100)/2 = 5,050',
      'Sum 3+7+11+15+19 (5 terms, a=3, d=4) = 5(3+19)/2 = 55',
      'Sum of odd numbers from 1 to 99: n=50, sum = 50(1+99)/2 = 2,500',
    ],
    commonMistakes: [
      'Counting number of terms incorrectly',
      'Using wrong first or last term',
      'Confusing with geometric series',
    ],
    relatedTechniques: ['geometric-series', 'sum-of-squares', 'telescoping-series'],
  },
  {
    id: 'geometric-series',
    name: 'Geometric Series Sum',
    category: 'algebraic-series',
    difficulty: 0.4,
    formula: '\\sum_{k=0}^{n-1} ar^k = a\\frac{r^n - 1}{r - 1} \\quad (r \\neq 1)',
    description: 'Sum of geometric sequence with first term a and common ratio r',
    whenToUse: [
      'Sequence has constant ratio between consecutive terms',
      'Exponential growth or decay pattern',
      'Powers of a constant',
    ],
    stepByStepHints: [
      'Step 1: Identify first term a, common ratio r, number of terms n',
      'Step 2: Apply formula: a(rⁿ - 1)/(r - 1)',
      'Step 3: If |r| < 1 and infinite series, use a/(1-r)',
      'Step 4: Verify by computing first few terms manually',
    ],
    examples: [
      'Sum 1+2+4+8+16 = 1(2⁵-1)/(2-1) = 31',
      'Sum 3+6+12+24 (a=3, r=2, n=4) = 3(2⁴-1)/(2-1) = 45',
      'Infinite: 1+1/2+1/4+... = 1/(1-1/2) = 2',
    ],
    commonMistakes: [
      'Using arithmetic series formula instead',
      'Forgetting -1 in numerator',
      'Wrong sign when r < 0',
      'Confusing finite and infinite series formulas',
    ],
    relatedTechniques: ['arithmetic-series', 'exponential-growth', 'binomial-theorem'],
  },

  // ===== NUMBER THEORY TECHNIQUES =====
  {
    id: 'modular-arithmetic',
    name: 'Modular Arithmetic Fundamentals',
    category: 'number-theory',
    difficulty: 0.4,
    formula: 'a \\equiv b \\pmod{m} \\iff m | (a-b)',
    description: 'Arithmetic with remainders; preserves addition, subtraction, multiplication',
    whenToUse: [
      'Problem asks for remainder when divided by m',
      'Divisibility conditions',
      'Last digits of large numbers',
      'Cyclic patterns',
    ],
    stepByStepHints: [
      'Step 1: Reduce all numbers modulo m',
      'Step 2: Perform operations (add/subtract/multiply) on reduced values',
      'Step 3: Take modulo m after each operation to keep numbers small',
      'Step 4: Remember: (a+b) mod m = ((a mod m) + (b mod m)) mod m',
      'Step 5: Warning: division requires modular inverse',
    ],
    examples: [
      'Find 23*45 mod 7: (23 mod 7)*(45 mod 7) = 2*3 = 6 mod 7',
      'Last digit of 3^100: 3^4 ≡ 1 (mod 10), so 3^100 = (3^4)^25 ≡ 1 (mod 10)',
      'Check if 1234567 divisible by 9: sum digits = 28, 2+8=10, 1+0=1, not divisible',
    ],
    commonMistakes: [
      'Trying to divide in modular arithmetic without modular inverse',
      'Forgetting to reduce intermediate results',
      'Confusing a ≡ b (mod m) with a = b',
      'Not recognizing cyclic patterns in powers',
    ],
    relatedTechniques: ['fermats-little-theorem', 'chinese-remainder', 'divisibility'],
  },
  {
    id: 'fermats-little-theorem',
    name: "Fermat's Little Theorem",
    category: 'number-theory',
    difficulty: 0.6,
    formula: 'a^{p-1} \\equiv 1 \\pmod{p} \\quad (\\text{if } p \\text{ prime, } \\gcd(a,p)=1)',
    description: 'For prime p and a not divisible by p, a^(p-1) ≡ 1 (mod p)',
    whenToUse: [
      'Computing large powers modulo prime',
      'Finding modular inverses (a^(-1) ≡ a^(p-2) mod p)',
      'Primality testing',
      'Cyclic patterns in powers mod prime',
    ],
    stepByStepHints: [
      'Step 1: Verify p is prime and gcd(a,p) = 1',
      'Step 2: For a^n mod p, compute n mod (p-1) first',
      'Step 3: Use a^(p-1) ≡ 1 to reduce exponent',
      'Step 4: Example: a^100 mod 7 = a^(100 mod 6) mod 7 = a^4 mod 7',
      'Step 5: For inverse: a^(-1) ≡ a^(p-2) (mod p)',
    ],
    examples: [
      '2^100 mod 11: 100 = 10*10, so 2^100 ≡ (2^10)^10 ≡ 1^10 ≡ 1 (mod 11)',
      'Find 3^(-1) mod 7: 3^(-1) ≡ 3^5 ≡ 243 ≡ 5 (mod 7)',
      'Check: 3*5 = 15 ≡ 1 (mod 7) ✓',
    ],
    commonMistakes: [
      'Applying to composite moduli (use Euler theorem instead)',
      'Forgetting gcd(a,p) = 1 condition',
      'Computing a^(p-1) directly instead of reducing exponent first',
    ],
    relatedTechniques: ['modular-arithmetic', 'euler-theorem', 'chinese-remainder'],
  },
  {
    id: 'prime-factorization',
    name: 'Prime Factorization',
    category: 'number-theory',
    difficulty: 0.3,
    formula: 'n = p_1^{a_1} \\cdot p_2^{a_2} \\cdot \\ldots \\cdot p_k^{a_k}',
    description: 'Every integer > 1 has unique prime factorization',
    whenToUse: [
      'Counting divisors',
      'GCD/LCM calculations',
      'Solving Diophantine equations',
      'Perfect square/cube tests',
    ],
    stepByStepHints: [
      'Step 1: Divide by smallest prime (2) repeatedly',
      'Step 2: Move to next prime (3, 5, 7, ...) when current prime does not divide',
      'Step 3: Stop when quotient is 1 or quotient is prime',
      'Step 4: Express as product of prime powers',
      'Step 5: Use for divisor count: τ(n) = (a₁+1)(a₂+1)...(aₖ+1)',
    ],
    examples: [
      '360 = 2³ × 3² × 5¹',
      'Number of divisors of 360: (3+1)(2+1)(1+1) = 24',
      'LCM(12, 18) = 2² × 3² = 36',
      'GCD(12, 18) = 2¹ × 3¹ = 6',
    ],
    commonMistakes: [
      'Missing a prime factor',
      'Stopping too early',
      'Confusing prime factorization with divisor listing',
    ],
    relatedTechniques: ['divisibility', 'gcd-lcm', 'diophantine-equations'],
  },

  // ===== COMBINATORICS TECHNIQUES =====
  {
    id: 'combinations',
    name: 'Combinations (n choose k)',
    category: 'combinatorics',
    difficulty: 0.3,
    formula: '\\binom{n}{k} = \\frac{n!}{k!(n-k)!}',
    description: 'Number of ways to choose k items from n items without regard to order',
    whenToUse: [
      'Selecting subset without caring about order',
      'Committee selection problems',
      'Binomial coefficient calculations',
      'Pascal triangle entries',
    ],
    stepByStepHints: [
      'Step 1: Identify n (total items) and k (items to choose)',
      'Step 2: Use formula C(n,k) = n!/(k!(n-k)!)',
      'Step 3: Simplify: compute n!/(n-k)! first, then divide by k!',
      'Step 4: Alternative: C(n,k) = C(n,n-k) for efficiency',
      'Step 5: Verify: C(n,0) = C(n,n) = 1, C(n,1) = n',
    ],
    examples: [
      'C(5,2) = 5!/(2!3!) = (5×4)/(2×1) = 10',
      'Ways to choose 3 people from 10: C(10,3) = 120',
      'C(52,5) = 2,598,960 (poker hands)',
    ],
    commonMistakes: [
      'Using permutation formula instead',
      'Computing factorials inefficiently',
      'Not recognizing C(n,k) = C(n,n-k) symmetry',
    ],
    relatedTechniques: ['permutations', 'binomial-theorem', 'pascals-triangle'],
  },
  {
    id: 'permutations',
    name: 'Permutations',
    category: 'combinatorics',
    difficulty: 0.3,
    formula: 'P(n,k) = \\frac{n!}{(n-k)!}',
    description: 'Number of ways to arrange k items from n items where order matters',
    whenToUse: [
      'Arrangement problems where order matters',
      'Ranking or ordering tasks',
      'Sequence generation',
    ],
    stepByStepHints: [
      'Step 1: Identify n (total items) and k (positions to fill)',
      'Step 2: Use formula P(n,k) = n!/(n-k)!',
      'Step 3: Alternative: n × (n-1) × (n-2) × ... × (n-k+1)',
      'Step 4: Special case: P(n,n) = n!',
      'Step 5: Verify with small example',
    ],
    examples: [
      'P(5,2) = 5!/(5-2)! = 5!/3! = 20',
      'Ways to arrange 3 books from 10: P(10,3) = 10×9×8 = 720',
      'Anagrams of "ABC": P(3,3) = 3! = 6',
    ],
    commonMistakes: [
      'Using combination formula when order matters',
      'Forgetting to account for repeated elements',
      'Not recognizing when order does NOT matter',
    ],
    relatedTechniques: ['combinations', 'factorial', 'derangements'],
  },
  {
    id: 'pigeonhole-principle',
    name: 'Pigeonhole Principle',
    category: 'combinatorics',
    difficulty: 0.5,
    formula: '\\text{If } n \\text{ items in } k \\text{ boxes, then at least one box has } \\lceil n/k \\rceil \\text{ items}',
    description: 'If you have more items than containers, at least one container must have multiple items',
    whenToUse: [
      'Proving existence without construction',
      'Finding guaranteed duplicates',
      'Birthday paradox type problems',
      'Graph coloring',
    ],
    stepByStepHints: [
      'Step 1: Identify the "pigeons" (items to place)',
      'Step 2: Identify the "holes" (categories/boxes)',
      'Step 3: If pigeons > holes, at least one hole has ≥2 pigeons',
      'Step 4: Generalized: ⌈n/k⌉ pigeons in at least one hole',
      'Step 5: Use for contradiction or existence proofs',
    ],
    examples: [
      'In any group of 13 people, at least 2 share birthday month',
      'Among 5 points in unit square, at least 2 are within √2/2 distance',
      'In sequence of n²+1 numbers, increasing or decreasing subsequence of length ≥n+1',
    ],
    commonMistakes: [
      'Not clearly defining pigeons and holes',
      'Assuming uniform distribution',
      'Forgetting ceiling function for generalized principle',
    ],
    relatedTechniques: ['counting-principles', 'extremal-combinatorics', 'graph-theory'],
  },

  // ===== INEQUALITY TECHNIQUES =====
  {
    id: 'am-gm-inequality',
    name: 'AM-GM Inequality',
    category: 'inequalities',
    difficulty: 0.5,
    formula: '\\frac{a_1 + a_2 + \\ldots + a_n}{n} \\geq \\sqrt[n]{a_1 a_2 \\ldots a_n}',
    description: 'Arithmetic mean ≥ Geometric mean, with equality iff all terms are equal',
    whenToUse: [
      'Proving inequalities with products and sums',
      'Optimization: minimize sum given fixed product (or vice versa)',
      'Finding maximum/minimum values',
    ],
    stepByStepHints: [
      'Step 1: Identify terms to apply AM-GM to',
      'Step 2: Write arithmetic mean ≥ geometric mean',
      'Step 3: Simplify geometric mean (often perfect power)',
      'Step 4: Check equality condition: all terms equal',
      'Step 5: Multiply both sides to clear fractions if needed',
    ],
    examples: [
      'For a,b > 0: (a+b)/2 ≥ √(ab), equality when a=b',
      'Minimize x + 1/x for x > 0: AM-GM gives x + 1/x ≥ 2√(x·1/x) = 2',
      'Prove a² + b² ≥ 2ab: Apply AM-GM to a² and b²',
    ],
    commonMistakes: [
      'Applying to negative numbers',
      'Forgetting equality condition',
      'Wrong direction of inequality',
      'Not checking if all terms are positive',
    ],
    relatedTechniques: ['cauchy-schwarz', 'power-mean-inequality', 'optimization'],
  },
  {
    id: 'cauchy-schwarz',
    name: 'Cauchy-Schwarz Inequality',
    category: 'inequalities',
    difficulty: 0.6,
    formula: '(a_1^2 + a_2^2 + \\ldots + a_n^2)(b_1^2 + b_2^2 + \\ldots + b_n^2) \\geq (a_1b_1 + a_2b_2 + \\ldots + a_nb_n)^2',
    description: 'Product of sum of squares ≥ square of sum of products',
    whenToUse: [
      'Inequalities with mixed products and squares',
      'Inner product bounds',
      'Triangle inequality derivations',
    ],
    stepByStepHints: [
      'Step 1: Identify two sequences (a₁,...,aₙ) and (b₁,...,bₙ)',
      'Step 2: Compute sum of squares for each sequence',
      'Step 3: Compute sum of products',
      'Step 4: Apply inequality: (Σa²)(Σb²) ≥ (Σab)²',
      'Step 5: Equality when sequences are proportional',
    ],
    examples: [
      '(a²+b²)(x²+y²) ≥ (ax+by)², equality when a/b = x/y',
      'Prove √(a₁²+...+aₙ²) + √(b₁²+...+bₙ²) ≥ √((a₁+b₁)²+...+(aₙ+bₙ)²)',
    ],
    commonMistakes: [
      'Wrong side of inequality',
      'Forgetting square on RHS',
      'Not checking equality condition',
    ],
    relatedTechniques: ['am-gm-inequality', 'triangle-inequality', 'quadratic-forms'],
  },

  // ===== PROBLEM-SOLVING STRATEGIES =====
  {
    id: 'working-backwards',
    name: 'Working Backwards',
    category: 'strategy',
    difficulty: 0.4,
    description: 'Start from desired result and reverse-engineer the path',
    whenToUse: [
      'Final state is simpler than initial state',
      'Construction problems',
      'Game theory (finding winning strategy)',
      'Proof by working from conclusion',
    ],
    stepByStepHints: [
      'Step 1: Write down the target/goal state',
      'Step 2: Ask "what must be true immediately before this?"',
      'Step 3: Repeat step 2 until you reach the starting state',
      'Step 4: Reverse the sequence to get forward solution',
      'Step 5: Verify forward path actually works',
    ],
    examples: [
      'Maze solving: start at exit, trace backwards to entrance',
      'Construction: "To have X, I need Y. To have Y, I need Z..."',
      'Induction proof: assume P(n) true, work backwards to P(n-1)',
    ],
    commonMistakes: [
      'Assuming reversibility when operations are not reversible',
      'Not verifying forward solution',
      'Getting lost in backwards reasoning',
    ],
    relatedTechniques: ['proof-by-induction', 'invariant-analysis', 'game-theory'],
  },
  {
    id: 'casework-analysis',
    name: 'Casework / Exhaustive Analysis',
    category: 'strategy',
    difficulty: 0.4,
    description: 'Break problem into mutually exclusive, exhaustive cases',
    whenToUse: [
      'Small number of cases (<10)',
      'Distinct scenarios with different behavior',
      'Parity arguments (odd/even)',
      'Sign analysis (positive/negative/zero)',
    ],
    stepByStepHints: [
      'Step 1: Identify the critical parameter to split on',
      'Step 2: Enumerate all possible cases',
      'Step 3: Verify cases are mutually exclusive (no overlap)',
      'Step 4: Verify cases are exhaustive (cover all possibilities)',
      'Step 5: Solve each case independently and combine results',
    ],
    examples: [
      'Absolute value: split |x-5| into cases x≥5 and x<5',
      'Parity: split into even n and odd n',
      'Modular: split into n≡0,1,2 (mod 3)',
    ],
    commonMistakes: [
      'Missing cases',
      'Overlapping cases',
      'Not combining results correctly',
      'Too many cases (consider different split)',
    ],
    relatedTechniques: ['modular-arithmetic', 'proof-techniques', 'counting-principles'],
  },
  {
    id: 'invariant-analysis',
    name: 'Invariant / Monovariant Analysis',
    category: 'strategy',
    difficulty: 0.6,
    description: 'Find quantity that remains constant (invariant) or changes monotonically (monovariant)',
    whenToUse: [
      'Process that repeats or iterates',
      'Game theory (proving impossibility)',
      'Parity arguments',
      'Proving something never happens',
    ],
    stepByStepHints: [
      'Step 1: Identify the process/operation that repeats',
      'Step 2: Look for quantity that does not change (invariant)',
      'Step 3: Or find quantity that always increases/decreases (monovariant)',
      'Step 4: Use invariant to prove impossibility or reachability',
      'Step 5: Common invariants: parity, sum, product, modular residue',
    ],
    examples: [
      'Checkers invariant: color of square determines parity of total moves',
      'Sum invariant: if operation preserves sum mod k, final sum ≡ initial sum (mod k)',
      'Monovariant: Euclidean algorithm always decreases, so must terminate',
    ],
    commonMistakes: [
      'Claiming invariant without proving it',
      'Not considering all operations',
      'Confusing invariant with monovariant',
    ],
    relatedTechniques: ['game-theory', 'modular-arithmetic', 'graph-coloring'],
  },
  {
    id: 'telescoping-series',
    name: 'Telescoping Series',
    category: 'algebraic-series',
    difficulty: 0.5,
    formula: '\\sum_{k=1}^{n} (a_k - a_{k+1}) = a_1 - a_{n+1}',
    description: 'Series where consecutive terms cancel, leaving only first and last',
    whenToUse: [
      'Sum of differences',
      'Partial fractions that simplify',
      'Consecutive term cancellation pattern',
    ],
    stepByStepHints: [
      'Step 1: Rewrite each term as difference of consecutive terms',
      'Step 2: Write out first few terms to see cancellation',
      'Step 3: Observe middle terms cancel',
      'Step 4: Only first and last terms remain',
      'Step 5: Simplify to final expression',
    ],
    examples: [
      'Σ(1/k - 1/(k+1)) from k=1 to n = 1 - 1/(n+1)',
      'Σ(√k - √(k-1)) from k=1 to n = √n - √0 = √n',
      '1/1·2 + 1/2·3 + ... + 1/n(n+1) = 1 - 1/(n+1)',
    ],
    commonMistakes: [
      'Not writing out enough terms to see pattern',
      'Incorrect cancellation',
      'Forgetting boundary terms',
    ],
    relatedTechniques: ['partial-fractions', 'arithmetic-series', 'sum-manipulation'],
  },

  // ===== GEOMETRY TECHNIQUES =====
  {
    id: 'pythagorean-theorem',
    name: 'Pythagorean Theorem',
    category: 'geometry',
    difficulty: 0.2,
    formula: 'a^2 + b^2 = c^2',
    description: 'In right triangle, sum of squares of legs equals square of hypotenuse',
    whenToUse: [
      'Right triangle problems',
      'Distance calculations in coordinate geometry',
      'Checking if triangle is right-angled',
    ],
    stepByStepHints: [
      'Step 1: Identify right angle in triangle',
      'Step 2: Label legs as a and b, hypotenuse as c',
      'Step 3: Apply a² + b² = c²',
      'Step 4: Solve for unknown side',
      'Step 5: Check reasonableness (c > a and c > b)',
    ],
    examples: [
      'Legs 3 and 4: c² = 9 + 16 = 25, so c = 5',
      'Distance from (0,0) to (3,4): √(3²+4²) = 5',
      'Pythagorean triples: (3,4,5), (5,12,13), (8,15,17)',
    ],
    commonMistakes: [
      'Applying to non-right triangles',
      'Confusing leg with hypotenuse',
      'Forgetting to take square root',
    ],
    relatedTechniques: ['distance-formula', 'coordinate-geometry', 'similarity'],
  },
  {
    id: 'triangle-inequality',
    name: 'Triangle Inequality',
    category: 'geometry',
    difficulty: 0.3,
    formula: '|a - b| < c < a + b',
    description: 'Sum of any two sides of triangle exceeds the third side',
    whenToUse: [
      'Determining if three lengths form valid triangle',
      'Proving geometric inequalities',
      'Distance bounds',
    ],
    stepByStepHints: [
      'Step 1: For sides a, b, c, check a+b > c',
      'Step 2: Also check b+c > a and a+c > b',
      'Step 3: Equivalently: |a-b| < c < a+b',
      'Step 4: All three must hold for valid triangle',
      'Step 5: Equality gives degenerate (collinear) case',
    ],
    examples: [
      'Sides 3, 4, 5: 3+4=7>5, 4+5=9>3, 3+5=8>4 ✓ Valid',
      'Sides 1, 2, 10: 1+2=3 < 10 ✗ Invalid',
      'Shortest path: straight line from A to B is shorter than any detour',
    ],
    commonMistakes: [
      'Checking only one inequality',
      'Forgetting strict inequality (equality = degenerate)',
      'Not considering all three sides',
    ],
    relatedTechniques: ['geometric-inequalities', 'distance-formula', 'optimization'],
  },

  // ===== CALCULUS & OPTIMIZATION =====
  {
    id: 'derivative-optimization',
    name: 'Derivative-based Optimization',
    category: 'calculus',
    difficulty: 0.5,
    formula: 'f\'(x) = 0 \\text{ at critical points}',
    description: 'Find maxima/minima by setting derivative to zero',
    whenToUse: [
      'Continuous optimization problems',
      'Finding maximum or minimum values',
      'Rate of change analysis',
    ],
    stepByStepHints: [
      'Step 1: Define function f(x) to optimize',
      'Step 2: Compute derivative f\'(x)',
      'Step 3: Set f\'(x) = 0 and solve for x',
      'Step 4: Check second derivative f\'\'(x) to classify (max/min)',
      'Step 5: Evaluate f at critical points and endpoints',
    ],
    examples: [
      'Maximize area of rectangle with perimeter 100: A = xy, x+y=50, dA/dx=0 gives x=y=25',
      'Minimize distance from point to curve',
      'Optimize profit/cost functions',
    ],
    commonMistakes: [
      'Not checking endpoints',
      'Not verifying max vs min with second derivative',
      'Forgetting domain constraints',
    ],
    relatedTechniques: ['am-gm-inequality', 'constraint-optimization', 'lagrange-multipliers'],
  },
];

// ============================================================================
// Seeding Implementation
// ============================================================================

/**
 * Convert technique to searchable text for embedding
 */
function techniqueToSearchableText(technique: MathTechnique): string {
  const parts = [
    `# ${technique.name}`,
    `Category: ${technique.category}`,
    `Difficulty: ${technique.difficulty}`,
    '',
    `## Description`,
    technique.description,
    '',
  ];

  if (technique.formula) {
    parts.push(`## Formula`, technique.formula, '');
  }

  parts.push(
    `## When to Use`,
    ...technique.whenToUse.map((use) => `- ${use}`),
    '',
    `## Step-by-Step Application`,
    ...technique.stepByStepHints.map((hint, i) => `${i + 1}. ${hint}`),
    '',
    `## Examples`,
    ...technique.examples.map((ex) => `- ${ex}`),
    ''
  );

  if (technique.commonMistakes.length > 0) {
    parts.push(
      `## Common Mistakes to Avoid`,
      ...technique.commonMistakes.map((mistake) => `- ${mistake}`),
      ''
    );
  }

  if (technique.relatedTechniques.length > 0) {
    parts.push(
      `## Related Techniques`,
      ...technique.relatedTechniques.map((rel) => `- ${rel}`),
      ''
    );
  }

  return parts.join('\n');
}

/**
 * Generate embedding using RuVector embeddings.js
 */
async function generateEmbedding(text: string): Promise<number[]> {
  const embeddingsScript = path.join(
    __dirname,
    '../.claude/skills/ruvector-codebase-index/embeddings.js'
  );

  try {
    const result = execSync(
      `node ${embeddingsScript} <<< ${JSON.stringify(text)}`,
      { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }
    );
    return JSON.parse(result);
  } catch (error) {
    console.error(`Failed to generate embedding for text: ${text.substring(0, 100)}...`);
    console.error(`Error: ${error}`);
    throw error;
  }
}

/**
 * Seed a single technique into RuVector
 */
async function seedTechnique(technique: MathTechnique): Promise<void> {
  console.log(`[INFO] Seeding technique: ${technique.id} (${technique.name})`);

  const searchableText = techniqueToSearchableText(technique);
  const embedding = await generateEmbedding(searchableText);

  // Store in RuVector using batch-indexer.js
  const batchIndexerScript = path.join(
    __dirname,
    '../.claude/skills/ruvector-codebase-index/batch-indexer.js'
  );

  const entry = {
    id: `math-technique-${technique.id}`,
    text: searchableText,
    vector: embedding,
    metadata: {
      type: 'math-technique',
      techniqueId: technique.id,
      name: technique.name,
      category: technique.category,
      difficulty: technique.difficulty,
      formula: technique.formula || null,
      whenToUse: technique.whenToUse,
      stepByStepHints: technique.stepByStepHints,
      examples: technique.examples,
      commonMistakes: technique.commonMistakes,
      relatedTechniques: technique.relatedTechniques,
    },
  };

  // Write to temp file for batch indexer
  const tempFile = `/tmp/math-technique-${technique.id}.json`;
  fs.writeFileSync(tempFile, JSON.stringify(entry));

  try {
    execSync(`node ${batchIndexerScript} ${tempFile}`, {
      encoding: 'utf-8',
      stdio: 'inherit',
    });
    console.log(`[SUCCESS] Seeded: ${technique.id}`);
  } catch (error) {
    console.error(`[ERROR] Failed to seed ${technique.id}:`, error);
    throw error;
  } finally {
    fs.unlinkSync(tempFile);
  }
}

/**
 * Main seeding function
 */
async function seedAllTechniques(): Promise<void> {
  console.log('═══════════════════════════════════════════════════════');
  console.log('   Mathematical Techniques Seeding');
  console.log('═══════════════════════════════════════════════════════');
  console.log('');
  console.log(`[INFO] Total techniques to seed: ${MATH_TECHNIQUES.length}`);
  console.log('');

  const startTime = Date.now();
  let successCount = 0;
  let failureCount = 0;

  for (const technique of MATH_TECHNIQUES) {
    try {
      await seedTechnique(technique);
      successCount++;
    } catch (error) {
      console.error(`[ERROR] Failed to seed ${technique.id}`);
      failureCount++;
    }
  }

  const endTime = Date.now();
  const duration = ((endTime - startTime) / 1000).toFixed(2);

  console.log('');
  console.log('═══════════════════════════════════════════════════════');
  console.log('   Seeding Complete');
  console.log('═══════════════════════════════════════════════════════');
  console.log(`[SUCCESS] Seeded: ${successCount} techniques`);
  console.log(`[FAILED]  Failed: ${failureCount} techniques`);
  console.log(`[TIMING]  Duration: ${duration}s`);
  console.log('');
}

/**
 * Query example: demonstrate retrieval
 */
async function queryExample(query: string): Promise<void> {
  console.log(`\n[QUERY] "${query}"`);

  const searchScript = path.join(
    __dirname,
    '../.claude/skills/ruvector-codebase-index/search.sh'
  );

  try {
    const results = execSync(
      `${searchScript} "${query}" --top 3`,
      { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }
    );
    console.log(results);
  } catch (error) {
    console.error(`[ERROR] Query failed: ${error}`);
  }
}

// ============================================================================
// CLI Execution
// ============================================================================

if (require.main === module) {
  (async () => {
    try {
      // Seed all techniques
      await seedAllTechniques();

      // Example queries to demonstrate retrieval
      console.log('\n═══════════════════════════════════════════════════════');
      console.log('   Example Queries');
      console.log('═══════════════════════════════════════════════════════');

      await queryExample('sum of squares formula');
      await queryExample('how to prove inequality');
      await queryExample('counting combinations');
      await queryExample('modular arithmetic with prime');

    } catch (error) {
      console.error('[FATAL] Seeding failed:', error);
      process.exit(1);
    }
  })();
}

export { MATH_TECHNIQUES, techniqueToSearchableText, seedTechnique, seedAllTechniques };
