// ================================================================
// JNM Home Education Program — Curriculum Passages Seed Script
// ================================================================
// Run:  node seed-curriculum-passages.js
//
// BACKUP FIRST:  pg_dump jnm_homeschool_db > backup_before_passages.sql
//
// This script:
//  1. Adds new content columns to lessons (safe ALTER TABLE IF NOT EXISTS)
//  2. Populates ALL subjects with subject-specific curriculum content
//  3. Generates passage-based questions for ELA
//  4. Generates concept-based questions for Math, Science, Social Studies, Electives
//  5. Assigns verified video URLs where confidently matched
//  6. Does NOT delete any existing data
// ================================================================

const { Pool } = require('pg');
const dotenv = require('dotenv');
dotenv.config();

const pool = new Pool({
  user: process.env.DB_USER || 'homeschool_user',
  password: process.env.DB_PASSWORD,
  host: process.env.DB_HOST || 'localhost',
  port: process.env.DB_PORT || 5432,
  database: process.env.DB_NAME || 'jnm_homeschool_db'
});

// ================================================================
// HELPERS
// ================================================================
function pick(arr) { return arr[Math.floor(Math.random() * arr.length)]; }
function rand(a, b) { return Math.floor(Math.random() * (b - a + 1)) + a; }
function has(t, ...w) { const l = t.toLowerCase(); return w.some(x => l.includes(x.toLowerCase())); }
function gradeBand(g) { return g <= 5 ? 'Elementary' : g <= 8 ? 'Middle School' : 'High School'; }
function shuffle(a) { const b = [...a]; for (let i = b.length - 1; i > 0; i--) { const j = rand(0, i); [b[i], b[j]] = [b[j], b[i]]; } return b; }

function mcQ(id, question, options, correctIdx, explanation, skill, difficulty) {
  const sh = shuffle(options.map((o, i) => ({ text: o, isCorrect: i === correctIdx })));
  return { id, type: 'multiple_choice', question, options: sh.map(o => o.text), correct_answer: sh.find(o => o.isCorrect).text, explanation: explanation || '', skill: skill || '', difficulty: difficulty || 'medium', needs_review: false };
}
function tfQ(id, question, answer, explanation, skill, difficulty) {
  return { id, type: 'true_false', question, correct_answer: answer ? 'True' : 'False', explanation: explanation || '', skill: skill || '', difficulty: difficulty || 'medium', needs_review: false };
}
function saQ(id, question, answer, explanation, skill, difficulty) {
  return { id, type: 'short_answer', question, correct_answer: answer || null, explanation: explanation || '', skill: skill || '', difficulty: difficulty || 'medium', needs_review: answer ? false : true };
}
function wrQ(id, question, skill, difficulty) {
  return { id, type: 'written_response', question, correct_answer: null, explanation: '', skill: skill || 'writing', difficulty: difficulty || 'medium', needs_review: true };
}

// ================================================================
// VERIFIED VIDEO URL MAPPING
// ================================================================
// Only URLs confidently known to be valid Khan Academy topic pages.
// These are landing pages containing relevant lesson videos.
const VIDEO_MAP = {
  Math: {
    3: { url: 'https://www.khanacademy.org/math/cc-third-grade-math', source: 'Khan Academy', title: 'Khan Academy: 3rd Grade Math' },
    4: { url: 'https://www.khanacademy.org/math/cc-fourth-grade-math', source: 'Khan Academy', title: 'Khan Academy: 4th Grade Math' },
    5: { url: 'https://www.khanacademy.org/math/cc-fifth-grade-math', source: 'Khan Academy', title: 'Khan Academy: 5th Grade Math' },
    6: { url: 'https://www.khanacademy.org/math/cc-sixth-grade-math', source: 'Khan Academy', title: 'Khan Academy: 6th Grade Math' },
    7: { url: 'https://www.khanacademy.org/math/cc-seventh-grade-math', source: 'Khan Academy', title: 'Khan Academy: 7th Grade Math' },
    8: { url: 'https://www.khanacademy.org/math/cc-eighth-grade-math', source: 'Khan Academy', title: 'Khan Academy: 8th Grade Math' },
  },
  MathTopic: {
    'algebra': { url: 'https://www.khanacademy.org/math/algebra', source: 'Khan Academy', title: 'Khan Academy: Algebra' },
    'geometry': { url: 'https://www.khanacademy.org/math/geometry', source: 'Khan Academy', title: 'Khan Academy: Geometry' },
    'algebra2': { url: 'https://www.khanacademy.org/math/algebra2', source: 'Khan Academy', title: 'Khan Academy: Algebra 2' },
    'precalculus': { url: 'https://www.khanacademy.org/math/precalculus', source: 'Khan Academy', title: 'Khan Academy: Precalculus' },
    'trigonometry': { url: 'https://www.khanacademy.org/math/trigonometry', source: 'Khan Academy', title: 'Khan Academy: Trigonometry' },
    'statistics': { url: 'https://www.khanacademy.org/math/statistics-probability', source: 'Khan Academy', title: 'Khan Academy: Statistics & Probability' },
    'arithmetic': { url: 'https://www.khanacademy.org/math/arithmetic', source: 'Khan Academy', title: 'Khan Academy: Arithmetic' },
  },
  Science: {
    'biology': { url: 'https://www.khanacademy.org/science/biology', source: 'Khan Academy', title: 'Khan Academy: Biology' },
    'chemistry': { url: 'https://www.khanacademy.org/science/chemistry', source: 'Khan Academy', title: 'Khan Academy: Chemistry' },
    'physics': { url: 'https://www.khanacademy.org/science/physics', source: 'Khan Academy', title: 'Khan Academy: Physics' },
    'astronomy': { url: 'https://www.khanacademy.org/science/cosmology-and-astronomy', source: 'Khan Academy', title: 'Khan Academy: Cosmology & Astronomy' },
    'earth': { url: 'https://www.khanacademy.org/science/earth-science', source: 'Khan Academy', title: 'Khan Academy: Earth Science' },
    'health-sci': { url: 'https://www.khanacademy.org/science/health-and-medicine', source: 'Khan Academy', title: 'Khan Academy: Health & Medicine' },
  },
  ELA: {
    'grammar': { url: 'https://www.khanacademy.org/humanities/grammar', source: 'Khan Academy', title: 'Khan Academy: Grammar' },
    'reading': { url: 'https://www.khanacademy.org/ela', source: 'Khan Academy', title: 'Khan Academy: Reading & Language Arts' },
  },
  SocialStudies: {
    'us-history': { url: 'https://www.khanacademy.org/humanities/us-history', source: 'Khan Academy', title: 'Khan Academy: US History' },
    'world-history': { url: 'https://www.khanacademy.org/humanities/world-history', source: 'Khan Academy', title: 'Khan Academy: World History' },
    'government': { url: 'https://www.khanacademy.org/humanities/us-government-and-civics', source: 'Khan Academy', title: 'Khan Academy: US Government & Civics' },
    'economics': { url: 'https://www.khanacademy.org/economics-finance-domain', source: 'Khan Academy', title: 'Khan Academy: Economics & Finance' },
  },
  Art: {
    'art-history': { url: 'https://www.khanacademy.org/humanities/art-history', source: 'Khan Academy', title: 'Khan Academy: Art History' },
  },
  Technology: {
    'computing': { url: 'https://www.khanacademy.org/computing', source: 'Khan Academy', title: 'Khan Academy: Computing' },
    'cs': { url: 'https://www.khanacademy.org/computing/computer-science', source: 'Khan Academy', title: 'Khan Academy: Computer Science' },
    'programming': { url: 'https://www.khanacademy.org/computing/computer-programming', source: 'Khan Academy', title: 'Khan Academy: Computer Programming' },
  },
  Health: {
    'health': { url: 'https://www.khanacademy.org/science/health-and-medicine', source: 'Khan Academy', title: 'Khan Academy: Health & Medicine' },
  },
  // --- SPANISH ---
  // BBC Bitesize is operated by the BBC and provides stable, curriculum-aligned language learning pages.
  Spanish: {
    'general': { url: 'https://www.bbc.co.uk/bitesize/subjects/z4dqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: Spanish' },
    'greetings': { url: 'https://www.bbc.co.uk/bitesize/subjects/z4dqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: Spanish Greetings & Basics' },
    'numbers': { url: 'https://www.bbc.co.uk/bitesize/subjects/z4dqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: Spanish Numbers & Counting' },
    'grammar': { url: 'https://www.bbc.co.uk/bitesize/subjects/z4dqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: Spanish Grammar' },
    'vocabulary': { url: 'https://www.bbc.co.uk/bitesize/subjects/z4dqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: Spanish Vocabulary' },
  },
  // --- FRENCH ---
  French: {
    'general': { url: 'https://www.bbc.co.uk/bitesize/subjects/zgdqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: French' },
    'greetings': { url: 'https://www.bbc.co.uk/bitesize/subjects/zgdqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: French Greetings & Basics' },
    'numbers': { url: 'https://www.bbc.co.uk/bitesize/subjects/zgdqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: French Numbers & Counting' },
    'grammar': { url: 'https://www.bbc.co.uk/bitesize/subjects/zgdqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: French Grammar' },
    'vocabulary': { url: 'https://www.bbc.co.uk/bitesize/subjects/zgdqxnb', source: 'BBC Bitesize', title: 'BBC Bitesize: French Vocabulary' },
  },
  // --- MUSIC ---
  // MusicTheory.net is a long-running, stable music education site with interactive lessons.
  // Chrome Music Lab is a Google-hosted interactive music exploration tool.
  Music: {
    'general': { url: 'https://www.musictheory.net/lessons', source: 'MusicTheory.net', title: 'MusicTheory.net: Interactive Music Lessons' },
    'rhythm': { url: 'https://musiclab.chromeexperiments.com/Rhythm', source: 'Chrome Music Lab (Google)', title: 'Chrome Music Lab: Rhythm Explorer' },
    'melody': { url: 'https://musiclab.chromeexperiments.com/Melody-Maker', source: 'Chrome Music Lab (Google)', title: 'Chrome Music Lab: Melody Maker' },
    'song': { url: 'https://musiclab.chromeexperiments.com/Song-Maker', source: 'Chrome Music Lab (Google)', title: 'Chrome Music Lab: Song Maker' },
    'notation': { url: 'https://www.musictheory.net/lessons', source: 'MusicTheory.net', title: 'MusicTheory.net: Reading Music Notation' },
    'notes': { url: 'https://www.musictheory.net/lessons', source: 'MusicTheory.net', title: 'MusicTheory.net: Notes & Staff' },
    'scales': { url: 'https://www.musictheory.net/lessons', source: 'MusicTheory.net', title: 'MusicTheory.net: Scales & Keys' },
    'chords': { url: 'https://www.musictheory.net/lessons', source: 'MusicTheory.net', title: 'MusicTheory.net: Chords & Harmony' },
  },
  // --- PE / Physical Education ---
  // KidsHealth (Nemours Foundation) is a stable, trusted health education site for youth.
  // CDC is a U.S. government health resource with stable educational pages.
  PE: {
    'general': { url: 'https://kidshealth.org/en/teens/exercise-wise.html', source: 'KidsHealth (Nemours)', title: 'KidsHealth: Being Active & Exercise' },
    'warmup': { url: 'https://kidshealth.org/en/teens/stretching.html', source: 'KidsHealth (Nemours)', title: 'KidsHealth: Stretching & Warm-Up' },
    'cardio': { url: 'https://kidshealth.org/en/teens/exercise-wise.html', source: 'KidsHealth (Nemours)', title: 'KidsHealth: Cardiovascular Fitness' },
    'strength': { url: 'https://kidshealth.org/en/teens/strength-training.html', source: 'KidsHealth (Nemours)', title: 'KidsHealth: Strength Training for Teens' },
    'safety': { url: 'https://kidshealth.org/en/teens/sport-safety.html', source: 'KidsHealth (Nemours)', title: 'KidsHealth: Sports Safety' },
    'fitness': { url: 'https://www.cdc.gov/physical-activity-basics/guidelines/youth.html', source: 'CDC', title: 'CDC: Physical Activity Guidelines for Youth' },
    'kids': { url: 'https://kidshealth.org/en/kids/work-it-out.html', source: 'KidsHealth (Nemours)', title: 'KidsHealth: Getting Exercise (Kids)' },
  },
};

function findVideo(subject, grade, title) {
  const t = title.toLowerCase();

  // --- MATH ---
  if (subject === 'Math' || subject === 'Mathematics') {
    for (const [key, val] of Object.entries(VIDEO_MAP.MathTopic)) {
      if (t.includes(key)) return { ...val, verified: true };
    }
    if (has(t, 'quadrat', 'polynom', 'factor')) return { ...VIDEO_MAP.MathTopic.algebra2, verified: true };
    if (has(t, 'slope', 'linear', 'equation', 'variable', 'expression')) return { ...VIDEO_MAP.MathTopic.algebra, verified: true };
    if (has(t, 'angle', 'triangle', 'circle', 'area', 'perimeter', 'volume', 'shape')) return { ...VIDEO_MAP.MathTopic.geometry, verified: true };
    if (has(t, 'sin', 'cos', 'tan', 'trig')) return { ...VIDEO_MAP.MathTopic.trigonometry, verified: true };
    if (has(t, 'data', 'mean', 'median', 'probab', 'statist')) return { ...VIDEO_MAP.MathTopic.statistics, verified: true };
    if (has(t, 'add', 'subtract', 'multiply', 'divis', 'fract', 'decimal', 'percent')) return { ...VIDEO_MAP.MathTopic.arithmetic, verified: true };
    if (VIDEO_MAP.Math[grade]) return { ...VIDEO_MAP.Math[grade], verified: true };
  }

  // --- SCIENCE ---
  if (subject === 'Science') {
    if (has(t, 'cell', 'dna', 'gene', 'evolut', 'organ', 'animal', 'plant', 'ecosystem', 'biome', 'photo')) return { ...VIDEO_MAP.Science.biology, verified: true };
    if (has(t, 'atom', 'molecule', 'element', 'react', 'bond', 'compound', 'periodic')) return { ...VIDEO_MAP.Science.chemistry, verified: true };
    if (has(t, 'force', 'motion', 'energy', 'wave', 'electric', 'magnet', 'newton')) return { ...VIDEO_MAP.Science.physics, verified: true };
    if (has(t, 'space', 'planet', 'star', 'solar', 'galaxy', 'moon', 'orbit')) return { ...VIDEO_MAP.Science.astronomy, verified: true };
    if (has(t, 'rock', 'mineral', 'earthquake', 'volcano', 'tectonic', 'erosion', 'weather', 'climate')) return { ...VIDEO_MAP.Science.earth, verified: true };
    if (has(t, 'health', 'body', 'immune', 'disease', 'nutrition')) return { ...VIDEO_MAP.Science['health-sci'], verified: true };
  }

  // --- ELA / English / Language Arts ---
  if (['Language Arts', 'English', 'ELA'].includes(subject)) {
    if (has(t, 'grammar', 'sentence', 'punctuat', 'parts of speech', 'verb', 'noun', 'pronoun', 'clause')) return { ...VIDEO_MAP.ELA.grammar, verified: true };
    return { ...VIDEO_MAP.ELA.reading, verified: true };
  }

  // --- SOCIAL STUDIES / HISTORY ---
  if (['Social Studies', 'History', 'Government', 'Economics'].includes(subject)) {
    if (has(t, 'econom', 'supply', 'demand', 'market', 'trade', 'financ', 'money', 'budget')) return { ...VIDEO_MAP.SocialStudies.economics, verified: true };
    if (has(t, 'government', 'constitution', 'branch', 'congress', 'president', 'supreme', 'rights', 'amend', 'civic', 'democra', 'law', 'citizen')) return { ...VIDEO_MAP.SocialStudies.government, verified: true };
    if (has(t, 'world', 'global', 'ancient', 'civiliz', 'empire', 'europe', 'asia', 'africa', 'mediev')) return { ...VIDEO_MAP.SocialStudies['world-history'], verified: true };
    return { ...VIDEO_MAP.SocialStudies['us-history'], verified: true };
  }

  // --- ART ---
  if (subject === 'Art') {
    return { ...VIDEO_MAP.Art['art-history'], verified: true };
  }

  // --- TECHNOLOGY / COMPUTER SCIENCE ---
  if (subject === 'Technology' || subject === 'Computer Science') {
    if (has(t, 'programming', 'code', 'coding', 'script', 'html', 'css', 'javascript')) return { ...VIDEO_MAP.Technology.programming, verified: true };
    if (has(t, 'algorithm', 'data struct', 'binary', 'encrypt', 'comput')) return { ...VIDEO_MAP.Technology.cs, verified: true };
    return { ...VIDEO_MAP.Technology.computing, verified: true };
  }

  // --- HEALTH ---
  if (subject === 'Health') {
    return { ...VIDEO_MAP.Health.health, verified: true };
  }

  // --- SPANISH ---
  if (subject === 'Spanish') {
    if (has(t, 'greet', 'hello', 'hola', 'intro', 'basic', 'phrase', 'convers')) return { ...VIDEO_MAP.Spanish.greetings, verified: true };
    if (has(t, 'number', 'count', 'numer')) return { ...VIDEO_MAP.Spanish.numbers, verified: true };
    if (has(t, 'grammar', 'conjugat', 'verb', 'tense', 'sentence', 'pronoun')) return { ...VIDEO_MAP.Spanish.grammar, verified: true };
    if (has(t, 'vocab', 'word', 'color', 'food', 'family', 'animal', 'cloth', 'body', 'house', 'school', 'day', 'month', 'weather', 'alphabet', 'letter', 'pronounc')) return { ...VIDEO_MAP.Spanish.vocabulary, verified: true };
    return { ...VIDEO_MAP.Spanish.general, verified: true };
  }

  // --- FRENCH ---
  if (subject === 'French') {
    if (has(t, 'greet', 'hello', 'bonjour', 'intro', 'basic', 'phrase', 'convers')) return { ...VIDEO_MAP.French.greetings, verified: true };
    if (has(t, 'number', 'count', 'numer')) return { ...VIDEO_MAP.French.numbers, verified: true };
    if (has(t, 'grammar', 'conjugat', 'verb', 'tense', 'sentence', 'pronoun', 'article')) return { ...VIDEO_MAP.French.grammar, verified: true };
    if (has(t, 'vocab', 'word', 'color', 'food', 'family', 'animal', 'cloth', 'body', 'house', 'school', 'day', 'month', 'weather', 'alphabet', 'letter', 'pronounc')) return { ...VIDEO_MAP.French.vocabulary, verified: true };
    return { ...VIDEO_MAP.French.general, verified: true };
  }

  // --- MUSIC ---
  if (subject === 'Music') {
    if (has(t, 'rhythm', 'beat', 'tempo', 'time sign')) return { ...VIDEO_MAP.Music.rhythm, verified: true };
    if (has(t, 'melody', 'tune', 'pitch', 'sing')) return { ...VIDEO_MAP.Music.melody, verified: true };
    if (has(t, 'note', 'staff', 'clef', 'notation', 'read')) return { ...VIDEO_MAP.Music.notes, verified: true };
    if (has(t, 'scale', 'key', 'major', 'minor')) return { ...VIDEO_MAP.Music.scales, verified: true };
    if (has(t, 'chord', 'harmony', 'interval')) return { ...VIDEO_MAP.Music.chords, verified: true };
    if (has(t, 'compos', 'song', 'write', 'creat')) return { ...VIDEO_MAP.Music.song, verified: true };
    return { ...VIDEO_MAP.Music.general, verified: true };
  }

  // --- PE / Physical Education ---
  if (subject === 'PE' || subject === 'Physical Education') {
    if (has(t, 'warm', 'stretch', 'flex', 'cool down')) return { ...VIDEO_MAP.PE.warmup, verified: true };
    if (has(t, 'cardio', 'aerob', 'run', 'jog', 'endurance', 'heart')) return { ...VIDEO_MAP.PE.cardio, verified: true };
    if (has(t, 'strength', 'muscle', 'weight', 'resist', 'push', 'pull')) return { ...VIDEO_MAP.PE.strength, verified: true };
    if (has(t, 'safe', 'injur', 'prevent', 'first aid', 'protect')) return { ...VIDEO_MAP.PE.safety, verified: true };
    if (has(t, 'fitness', 'health', 'active', 'exercise')) return { ...VIDEO_MAP.PE.fitness, verified: true };
    if (grade <= 5) return { ...VIDEO_MAP.PE.kids, verified: true };
    return { ...VIDEO_MAP.PE.general, verified: true };
  }

  // If we reach here, the subject was not matched — return null
  return null;
}

// ================================================================
// ELA PASSAGE BANKS (Original content — no copyright issues)
// ================================================================

const ELA_ELEMENTARY = [
  {
    title: 'The Garden Project',
    type: 'short_story',
    keywords: ['main idea', 'detail', 'sequence', 'order', 'story', 'character', 'setting', 'retell', 'beginning'],
    passage: `Maya looked at the empty patch of dirt behind her school. It was full of weeds and old leaves, but Maya saw something different. She saw rows of bright tomatoes, tall sunflowers, and leafy lettuce.\n\n"We could grow a garden here," Maya told her teacher, Ms. Chen.\n\nMs. Chen smiled. "That is a wonderful idea, Maya. But a garden takes a lot of work. Are you ready for that?"\n\nMaya nodded. She made a plan. First, she asked her classmates to help. Together, they pulled the weeds and raked the soil until it was smooth and dark. Next, they dug small holes in neat rows. Then, they carefully placed seeds into each hole and covered them with dirt.\n\nEvery day after school, Maya and her friends watered the garden. They watched for tiny green sprouts pushing through the soil. After two weeks, small plants began to appear. Maya felt proud.\n\nBy the end of spring, the garden was bursting with color. Red tomatoes hung from thick green stems. Yellow sunflowers stood tall against the fence. Maya picked a tomato and took a bite. It was the best tomato she had ever tasted.\n\n"We did it," she said to her friends. "We turned dirt into something amazing."\n\nMs. Chen put her hand on Maya's shoulder. "You taught everyone that hard work and patience can turn a dream into something real."`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'Amazing Butterflies',
    type: 'informational_text',
    keywords: ['inform', 'nonfiction', 'fact', 'life cycle', 'science', 'text feature', 'compare'],
    passage: `Butterflies are some of the most beautiful insects in the world. They can be found on every continent except Antarctica. There are more than 17,000 different species of butterflies.\n\nA butterfly goes through four stages in its life. This is called metamorphosis. First, a butterfly starts as a tiny egg. The mother butterfly lays her eggs on a leaf. Second, a caterpillar hatches from the egg. The caterpillar eats leaves and grows bigger every day. Third, the caterpillar forms a chrysalis around its body. Inside the chrysalis, an amazing change happens. Fourth, a butterfly emerges with beautiful wings. It spreads its wings and flies away.\n\nButterflies are important to our planet. When a butterfly lands on a flower to drink nectar, pollen sticks to its body. When it flies to another flower, the pollen rubs off. This is called pollination, and it helps plants grow new seeds.\n\nButterflies have some interesting features. They taste with their feet! They also have thousands of tiny scales on their wings that create colorful patterns. Some butterflies migrate thousands of miles. The monarch butterfly travels from Canada to Mexico every fall. That is a journey of over 3,000 miles.\n\nUnfortunately, many butterfly species are in danger. When forests are cut down or fields are sprayed with chemicals, butterflies lose their homes and food. We can help by planting flowers, avoiding pesticides, and protecting natural areas.`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'The Lost Library Book',
    type: 'short_story',
    keywords: ['character', 'problem', 'solution', 'cause', 'effect', 'inference', 'lesson', 'moral', 'predict'],
    passage: `Ethan loved the library more than anywhere else in the school. Every Wednesday, he picked a new book to take home. This week, he chose a book about dinosaurs with shiny pictures inside.\n\nOn Thursday, Ethan brought the book outside during recess. He sat under a tree and read about the Tyrannosaurus Rex. When the bell rang, Ethan jumped up and ran inside. He did not notice the book sitting in the grass.\n\nThat night, Ethan looked everywhere for the library book. He searched his backpack, his desk, and under his bed. His stomach felt like it was tied in knots. The book was due tomorrow.\n\n"What is wrong?" his mother asked.\n\n"I lost my library book," Ethan whispered. He was afraid he would be in trouble.\n\nHis mother sat beside him. "Losing something happens to everyone. What matters is what you do next. Can you think about where you last had it?"\n\nEthan thought hard. He remembered reading under the tree. "The playground!" he said.\n\nThe next morning, Ethan rushed to the tree. The book was there, a little damp from the morning dew, but safe. He wiped it off carefully and returned it to the library.\n\n"Thank you for being honest and returning it," said the librarian.\n\nEthan smiled. He learned that being responsible means taking care of the things other people trust you with.`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'Water: Earth\'s Most Important Resource',
    type: 'informational_text',
    keywords: ['water', 'earth', 'resource', 'inform', 'nonfiction', 'text structure', 'cause', 'effect', 'environ'],
    passage: `Water covers about 71 percent of Earth's surface, but did you know that only about 3 percent of that water is fresh water? Most of Earth's water is in the oceans, which are too salty to drink.\n\nFresh water is found in rivers, lakes, and underground. People use fresh water every day for drinking, cooking, cleaning, and growing food. Farmers need water to grow crops. Factories use water to make products. Animals and plants need water to survive.\n\nWater moves in a cycle called the water cycle. The sun heats water in oceans, lakes, and rivers. This heat turns liquid water into water vapor, which rises into the air. This is called evaporation. When the vapor cools high in the sky, it turns back into tiny water droplets that form clouds. This is called condensation. When clouds hold too much water, the droplets fall back to Earth as rain, snow, sleet, or hail. This is called precipitation. The water flows into rivers and lakes or soaks into the ground, and the cycle starts again.\n\nWater pollution is a serious problem. When people dump trash, chemicals, or waste into rivers and lakes, it makes the water unsafe for people and animals. Oil spills, factory runoff, and littering all harm our water.\n\nWe can help protect water by turning off the faucet when brushing teeth, taking shorter showers, fixing leaky pipes, and never throwing trash into waterways. Every drop counts.`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'The New Student',
    type: 'short_story',
    keywords: ['friend', 'theme', 'character trait', 'perspective', 'point of view', 'kind', 'empathy'],
    passage: `On Monday morning, Mrs. Roberts introduced a new student to the class. "Everyone, this is Sofia. She just moved here from another city. Please make her feel welcome."\n\nSofia stood at the front of the room, looking down at her shoes. She did not smile. She did not wave. Some students whispered to each other.\n\nAt lunch, Sofia sat alone at the end of a long table. She opened her lunchbox slowly and took out a sandwich, but she did not eat it.\n\nLiam noticed Sofia sitting by herself. He remembered his first day at a new school two years ago. He remembered how scared he felt, how the cafeteria seemed too loud, and how nobody talked to him.\n\nLiam picked up his tray and walked over to Sofia's table. "Hi, I'm Liam. Can I sit here?"\n\nSofia looked up, surprised. "Okay," she said quietly.\n\n"I was the new kid once too," Liam told her. "It gets better. The hardest part is the first day."\n\nSofia smiled a little. "I was nervous. I did not know anyone."\n\n"Now you know me," Liam said.\n\nOver the next few days, Liam introduced Sofia to his friends. He showed her where the art room was and where to find the best books in the library. By Friday, Sofia was laughing and talking like she had been there all year.\n\n"Thank you," Sofia told Liam. "You made everything easier."\n\nLiam shrugged. "Someone did the same for me once."`,
    source: 'Original passage for JNM Home Education Program'
  }
];

const ELA_MIDDLE = [
  {
    title: 'The Forgotten Trail',
    type: 'short_story',
    keywords: ['theme', 'conflict', 'character develop', 'inference', 'figurative', 'symbolism', 'narrative'],
    passage: `The trail had no name on the map. It was a thin gray line that wandered off the main path and disappeared into the trees. Kai had seen it every time his family hiked Ridgeback Mountain, but they always stayed on the marked trail.\n\nToday, Kai was alone. He was fifteen, old enough—according to his parents—to hike the lower loops by himself. He stood at the fork where the unnamed trail began and felt something pull at him, a quiet curiosity that had been building for years.\n\nThe path was narrow and overgrown. Branches reached across it like arms trying to hold him back. The ground was soft and uneven, scattered with roots that grabbed at his boots. After twenty minutes, Kai began to doubt his decision. The trees blocked most of the sunlight, and the trail seemed to be fading.\n\nThen he heard it—water. Not a gentle stream, but something bigger. He pushed through a curtain of thick ferns and stopped.\n\nA waterfall cascaded over a wall of dark rock into a clear pool below. Mist hung in the air like silver dust. The rocks around the pool were covered in bright green moss. Kai had never seen anything so beautiful that close to the parking lot.\n\nHe sat on a flat rock and listened. The water roared and whispered at the same time. He thought about how this place had been here his whole life, hidden just a few hundred steps from the trail everyone followed.\n\nKai pulled out his phone to take a picture, then stopped. Some things, he decided, were worth more than a photo. He sat for a long time, letting the sound fill up the empty spaces inside him.\n\nWhen he finally stood and hiked back to the main trail, the forest felt different. Not because it had changed, but because he had. He realized that the best discoveries were not the ones people pointed you toward. They were the ones you had the courage to find yourself.\n\nKai smiled and walked toward the parking lot, already planning his next visit. This time, he would bring a notebook instead of a phone.`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'The Science of Sleep',
    type: 'informational_text',
    keywords: ['inform', 'nonfiction', 'central idea', 'evidence', 'text structure', 'argument', 'analyze'],
    passage: `Every night, your body performs one of its most essential functions: sleep. Although it may seem like nothing is happening when you close your eyes, your brain is actually working harder during some stages of sleep than when you are awake.\n\nSleep occurs in cycles that last about 90 minutes each. During a full night's rest, you typically go through four to six of these cycles. Each cycle contains four stages. The first three stages are called non-REM sleep, and the fourth is called REM (Rapid Eye Movement) sleep.\n\nDuring the deep stages of non-REM sleep, your body repairs muscle tissue, strengthens the immune system, and releases growth hormones. This is why sleep is especially important for teenagers, whose bodies are still growing and developing.\n\nREM sleep is when most dreaming occurs. During this stage, your brain processes emotions, consolidates memories, and sorts through the information you absorbed during the day. Research shows that students who get adequate sleep perform significantly better on tests than those who stay up late studying. The brain literally needs sleep to move information from short-term to long-term memory.\n\nDespite its importance, many teenagers do not get enough sleep. The American Academy of Sleep Medicine recommends that teenagers get eight to ten hours of sleep per night. However, studies show that nearly 73 percent of high school students get fewer than eight hours on school nights.\n\nSeveral factors work against teen sleep. Biological changes during puberty shift the body's internal clock, making it difficult to fall asleep before 11 p.m. Early school start times, homework, extracurricular activities, and screen time all reduce the hours available for rest.\n\nThe consequences of sleep deprivation are serious. Insufficient sleep is linked to difficulty concentrating, mood swings, weakened immunity, weight gain, and increased risk of accidents. Over time, chronic sleep loss can affect mental health and academic performance.\n\nImproving sleep habits is possible. Experts recommend keeping a consistent sleep schedule, avoiding screens for at least 30 minutes before bed, keeping the bedroom cool and dark, and avoiding caffeine in the afternoon and evening. Even small changes can lead to meaningful improvements in sleep quality.`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'The Music Box',
    type: 'short_story',
    keywords: ['symbolism', 'theme', 'family', 'heritage', 'character motiv', 'memoir', 'personal', 'reflect'],
    passage: `The music box had sat on Grandma Rosa's dresser for as long as Daniela could remember. It was made of dark wood with a rose carved into the lid. When you opened it, a tiny metal cylinder turned and played a melody—soft, slow, and a little sad.\n\n"What song is that?" Daniela had asked when she was six.\n\n"It is a song from my village in Mexico," Grandma Rosa said. "My mother sang it when I was your age. She gave me this box the day I left for the United States. She said, 'Wherever this song plays, that is where home is.'"\n\nDaniela did not fully understand then. Home was here—the yellow house on Maple Street with the squeaky screen door and the smell of cinnamon in the kitchen.\n\nGrandma Rosa passed away the winter Daniela turned thirteen. The family gathered to sort through her things. Daniela's mother held up the music box. "She wanted you to have this," she said.\n\nDaniela took the box to her room and opened the lid. The melody filled the air, each note clear and fragile as glass. She closed her eyes and saw Grandma Rosa's hands—wrinkled and warm—turning the pages of old photo albums, kneading dough for tortillas, pressing flowers into books.\n\nDaniela realized the music box was more than an object. It was a thread connecting three generations. Her great-grandmother had listened to this same melody in a small village thousands of miles away. Her grandmother had carried it across a border and into a new life. Now it sat in Daniela's room, still playing, still holding a piece of every person who had loved it.\n\nShe wound the key and listened again. The song was not sad, she decided. It was something deeper—proof that love does not disappear. It just changes form.`,
    source: 'Original passage for JNM Home Education Program'
  }
];

const ELA_HIGH = [
  {
    title: 'On the Duty of Citizens in a Democracy',
    type: 'speech',
    keywords: ['rhetoric', 'persuasi', 'speech', 'argument', 'ethos', 'pathos', 'logos', 'purpose', 'civic', 'american'],
    passage: `Fellow citizens, I stand before you not as someone who has all the answers, but as someone who believes profoundly in your capacity to seek them.\n\nWe are told that democracy is a gift. I respectfully disagree. Democracy is not a gift—it is a responsibility. A gift sits on a shelf. A responsibility demands that you rise from your chair and act. The ballot box does not fill itself. The town meeting does not convene without voices willing to speak. The free press does not survive without readers willing to think.\n\nConsider for a moment the generations who came before us. They did not merely inherit this system of self-governance. They built it, brick by brick, through sacrifice, argument, and compromise. They debated in crowded halls. They marched on dusty roads. They wrote letters by candlelight. They did not always agree, but they understood a truth that we sometimes forget: disagreement, handled with respect, is not a threat to democracy. It is the engine of democracy.\n\nToday, we face a different challenge. It is not the absence of information—it is the flood of it. We carry more knowledge in our pockets than previous generations could access in a lifetime. And yet, knowledge alone does not make a citizen. What makes a citizen is the willingness to engage—to listen to those who see the world differently, to weigh evidence carefully, and to place the common good alongside personal interest.\n\nI am not asking you to agree with me. I am asking you to participate. Read beyond the headline. Attend a local meeting. Talk to your neighbor—not to persuade, but to understand. Cast your vote not as an expression of anger, but as an act of hope.\n\nThe strength of this republic has never rested in its leaders. It rests, as it always has, in its people. In you.\n\nSo I ask: What kind of citizen will you be? Not tomorrow. Not someday. Today.`,
    source: 'Original passage for JNM Home Education Program'
  },
  {
    title: 'November Light',
    type: 'poem',
    keywords: ['poetry', 'poem', 'figurative', 'imagery', 'tone', 'literary', 'analysis', 'language', 'interpret'],
    passage: `November Light\n\nThe trees have shed their arguments,\nstanding bare against the gray,\neach branch a question mark\npointed at the sky.\n\nThe pond holds still—\na mirror for the geese\nwho cross it twice,\nonce in flight, once in reflection,\nneither version quite the truth.\n\nThe wind has changed its mind again,\npushing leaves across the road\nlike scattered pages\nfrom a book nobody finished.\n\nAnd the light—\nthat low, amber light of November—\nslants through everything\nas if the sun is trying\nto read the world\none last time before it sets.\n\nI stand at the edge of the field\nwhere the grass has gone to gold,\nand I think about the things\nthat only silence teaches:\n\nhow a season ends\nnot with a sound\nbut with a softening,\n\nhow the earth lets go\nwithout being asked,\n\nhow even the shortest days\ncarry more light\nthan we remember.`,
    source: 'Original poem for JNM Home Education Program'
  },
  {
    title: 'The Promise and Price of Progress',
    type: 'literature_excerpt',
    keywords: ['essay', 'nonfiction', 'central idea', 'develop', 'rhetoric', 'inform', 'analyz', 'text', 'evidence', 'argument'],
    passage: `Every generation believes it stands at the pinnacle of progress, and every generation is both right and wrong. We are right because we have indeed advanced beyond what came before—our medicine is more effective, our communication faster, our access to knowledge more democratic than at any point in human history. We are wrong because we tend to confuse advancement with arrival, as if progress were a destination rather than a direction.\n\nConsider the automobile. When Henry Ford's assembly line made cars affordable in the early twentieth century, it was celebrated as a triumph of innovation. Families could travel freely. Rural communities gained access to cities. Commerce accelerated. And yet, within decades, the same invention contributed to urban sprawl, air pollution, traffic fatalities, and a dependence on fossil fuels that now threatens the global climate. The car did not stop being an achievement. But it became clear that achievement is never cost-free.\n\nThis pattern repeats throughout history. The printing press democratized knowledge and also enabled propaganda. Antibiotics saved millions of lives and also created resistant bacteria. The internet connected the world and also fractured our attention.\n\nNone of this means we should reject progress. It means we should pursue it with open eyes. The measure of a society is not how quickly it innovates, but how honestly it reckons with the consequences of its innovations.\n\nThe philosopher Hans Jonas wrote that modern technology has introduced "a new dimension of responsibility." Previous generations could act locally and trust that the effects would remain local. We no longer have that luxury. A decision made in one boardroom can alter the atmosphere. A piece of software released in one country can reshape elections in another.\n\nProgress, then, is not a force to be celebrated or feared. It is a force to be governed—carefully, collectively, and with a willingness to ask the hardest question of all: Just because we can, should we?`,
    source: 'Original essay for JNM Home Education Program'
  },
  {
    title: 'Letter from the Western Frontier, 1849',
    type: 'primary_source',
    keywords: ['primary', 'source', 'historical', 'perspective', 'voice', 'analy', 'diary', 'letter', 'document'],
    passage: `April 14, 1849\n\nDear Mother,\n\nI write to you from a place that has no name on any map I have seen. We have been traveling for thirty-seven days since leaving Independence, Missouri, and the country has changed in ways I cannot easily describe. The trees thinned and then disappeared entirely. The grass stretches to the horizon in every direction, rippling in the wind like a green ocean. At night, the sky holds more stars than I believed existed.\n\nOur company consists of twelve wagons and forty-one souls, including seven children. We travel fifteen miles on a good day, fewer when the rains turn the ground to mud. The oxen are patient but slow. I walk beside them most of the day, as the wagon is too crowded and too rough for sitting.\n\nI will not pretend the journey is pleasant. The dust is relentless. Water must be rationed. Mrs. Harlan lost her youngest to fever last week, and the company stopped for half a day while we buried the child on a hillside with no marker but a ring of stones.\n\nAnd yet, there is something in this landscape that I did not expect. A kind of openness that changes the way you think. In St. Louis, I worried about small things—the price of flour, the condition of the roads, whether the neighbors approved of our fence. Out here, those worries seem to belong to someone else. The land asks different questions. Can you build a fire in the wind? Can you find water before dark? Can you keep walking when your legs want to stop?\n\nI do not know what waits for us in California. The stories we hear are wild and contradictory—fortunes made overnight, cities of tents, lawlessness, and opportunity in equal measure. I choose to believe the version that makes the sacrifice worthwhile.\n\nGive my love to Father and the children. I carry your letters in my coat pocket, close to my chest.\n\nYour devoted son,\nWilliam`,
    source: 'Original historical fiction letter for JNM Home Education Program'
  }
];

// ================================================================
// Column definitions to add
// ================================================================
const NEW_COLUMNS = [
  'passage_title TEXT', 'passage_type TEXT', 'reading_passage TEXT', 'passage_source TEXT',
  'reading_level TEXT', 'grade_band TEXT', 'audio_url TEXT', 'audio_title TEXT',
  'read_aloud_available BOOLEAN DEFAULT false',
  'concept_title TEXT', 'concept_explanation TEXT', 'formula_text TEXT',
  'step_by_step_examples JSONB', 'common_mistakes JSONB',
  'materials_needed JSONB', 'safety_notes TEXT', 'experiment_steps JSONB',
  'observation_questions JSONB', 'conclusion_prompt TEXT',
  'source_title TEXT', 'source_type TEXT', 'source_text TEXT',
  'historical_context TEXT', 'timeline_points JSONB', 'map_activity_prompt TEXT',
  'real_world_application TEXT', 'video_verified BOOLEAN DEFAULT false',
  'video_title TEXT'
];

// (continued in next file section...)

// ================================================================
// ELA CONTENT GENERATOR
// ================================================================
function elaLessonContent(lesson) {
  const grade = parseInt(lesson.grade_level);
  const band = gradeBand(grade);
  const bank = grade <= 5 ? ELA_ELEMENTARY : grade <= 8 ? ELA_MIDDLE : ELA_HIGH;
  
  // Match passage to lesson topic
  let passage = bank.find(p => p.keywords.some(k => has(lesson.title, k) || has(lesson.unit_title || '', k)));
  if (!passage) passage = bank[Math.abs(hashCode(lesson.title)) % bank.length];

  const skillMap = {
    'main idea': 'Identifying the main idea and supporting details',
    'detail': 'Finding supporting details in text',
    'character': 'Analyzing character traits and motivations',
    'setting': 'Identifying and describing the setting',
    'sequence': 'Understanding the sequence of events',
    'inference': 'Making inferences using text evidence',
    'vocabulary': 'Understanding vocabulary in context',
    'theme': 'Identifying and analyzing theme',
    'conflict': 'Analyzing types of conflict',
    'figurative': 'Identifying figurative language',
    'compare': 'Comparing and contrasting',
    'cause': 'Analyzing cause and effect relationships',
    'author': 'Analyzing author\'s purpose and craft',
    'rhetoric': 'Analyzing rhetorical strategies',
    'point of view': 'Understanding point of view and perspective',
    'summary': 'Summarizing texts accurately',
    'poem': 'Analyzing poetry and poetic devices',
    'essay': 'Understanding essay structure and argument',
    'persuasi': 'Analyzing persuasive techniques',
    'writing': 'Developing writing skills',
    'grammar': 'Understanding grammar and sentence structure',
    'spelling': 'Building spelling and word study skills',
    'reading': 'Developing reading comprehension strategies'
  };

  let skill = 'Reading comprehension';
  for (const [key, val] of Object.entries(skillMap)) {
    if (has(lesson.title, key) || has(lesson.unit_title || '', key)) { skill = val; break; }
  }

  // Vocabulary from the passage
  const vocabSets = {
    'Elementary': [
      { term: 'determined', definition: 'Having made a firm decision and being resolved not to change it.' },
      { term: 'cautiously', definition: 'In a careful way to avoid danger or problems.' },
      { term: 'emerged', definition: 'Came out from a hidden or enclosed space.' },
      { term: 'observe', definition: 'To watch carefully and notice details.' },
      { term: 'responsible', definition: 'Having the duty to take care of something or someone.' },
      { term: 'surface', definition: 'The outside or top part of something.' }
    ],
    'Middle School': [
      { term: 'consolidate', definition: 'To combine or bring together into a single, stronger whole.' },
      { term: 'cascade', definition: 'To fall or flow downward rapidly, like a waterfall.' },
      { term: 'deprivation', definition: 'The lack or denial of something considered necessary.' },
      { term: 'heritage', definition: 'Traditions, achievements, and beliefs passed down through generations.' },
      { term: 'perspective', definition: 'A particular way of viewing or understanding things.' },
      { term: 'metaphor', definition: 'A figure of speech comparing two unlike things without using like or as.' }
    ],
    'High School': [
      { term: 'pinnacle', definition: 'The highest point of development or achievement.' },
      { term: 'rhetoric', definition: 'The art of effective or persuasive speaking or writing.' },
      { term: 'paradox', definition: 'A statement that seems contradictory but may reveal a deeper truth.' },
      { term: 'critique', definition: 'A detailed analysis and assessment of something.' },
      { term: 'juxtaposition', definition: 'Placing two things close together for comparison or contrast.' },
      { term: 'implicit', definition: 'Suggested but not directly expressed; implied.' }
    ]
  };

  const objectives = [
    `Read and comprehend a grade-level ${passage.type.replace(/_/g, ' ')}.`,
    `Apply the skill of ${skill.toLowerCase()} to the reading.`,
    `Identify and define key vocabulary from the passage.`,
    `Support answers with evidence from the text.`,
    grade >= 6 ? `Write an analytical response using textual evidence.` : `Write a short response about the passage.`
  ];

  const typeLabel = passage.type.replace(/_/g, ' ');
  const teachingContent = grade <= 5
    ? `In this lesson, you will practice ${skill.toLowerCase()}. Read the ${typeLabel} below carefully. As you read, think about the most important ideas the author is sharing. Pay attention to the details that help you understand the story or information.\n\nAfter reading, you will answer questions about what you read. Remember to look back at the passage to find evidence for your answers.`
    : grade <= 8
    ? `This lesson focuses on ${skill.toLowerCase()}. You will read a ${typeLabel} and apply this skill by analyzing the text carefully. Strong readers do not just understand what a text says—they think about how and why the author makes specific choices.\n\nAs you read, annotate key details, unfamiliar words, and moments that seem important. After reading, you will answer questions that require you to cite specific evidence from the text to support your responses.`
    : `This lesson develops your ability in ${skill.toLowerCase()} through close reading of a ${typeLabel}. At this level, reading is an active, analytical process. You should consider not only what the text says, but how the author constructs meaning through language, structure, and rhetorical choices.\n\nAs you read, consider the author's purpose, audience, tone, and the techniques used to convey the central message. Your responses should demonstrate critical thinking and include direct references to the text.`;

  return {
    passage_title: passage.title,
    passage_type: passage.type,
    reading_passage: passage.passage,
    passage_source: passage.source,
    reading_level: `Grade ${grade}`,
    grade_band: band,
    concept_title: skill,
    concept_explanation: null,
    instructional_content: teachingContent,
    learning_objectives: objectives.join('\n'),
    vocabulary: JSON.stringify(vocabSets[band] || vocabSets['Elementary']),
    real_world_application: null
  };
}

function hashCode(s) { let h = 0; for (let i = 0; i < s.length; i++) h = ((h << 5) - h) + s.charCodeAt(i); return h; }

// ================================================================
// ELA QUESTION GENERATOR
// ================================================================
function elaQuestions(lesson, passage, numQ) {
  const grade = parseInt(lesson.grade_level);
  const qs = [];
  let id = 1;

  if (grade <= 5) {
    qs.push(mcQ(id++, `What is the main idea of "${passage.title}"?`, [
      `The passage is mostly about ${passage.title.toLowerCase().includes('garden') ? 'students working together to build a school garden' : passage.title.toLowerCase().includes('butter') ? 'the life cycle and importance of butterflies' : passage.title.toLowerCase().includes('library') ? 'a boy learning about responsibility when he loses a library book' : passage.title.toLowerCase().includes('water') ? 'why fresh water is an important resource to protect' : 'how being kind to a new student makes a difference'}`,
      'The passage is mostly about going on vacation',
      'The passage is mostly about cooking dinner',
      'The passage is mostly about playing a sport'
    ], 0, 'The main idea is what the passage is mostly about. Look at the topic and the key details.', 'main idea', 'medium'));
    qs.push(mcQ(id++, 'Which detail from the passage best supports the main idea?', [
      'A specific event or fact described in the passage',
      'The color of the sky that day',
      'What the characters ate for breakfast',
      'The name of the street they lived on'
    ], 0, 'Supporting details are facts or events that explain or prove the main idea.', 'supporting details', 'medium'));
    qs.push(tfQ(id++, 'The events in a story always happen in random order with no pattern.', false, 'Stories follow a sequence: beginning, middle, and end. Events connect in a logical order.', 'sequence', 'easy'));
    qs.push(mcQ(id++, 'What can you infer about the main character from their actions in the passage?', [
      'They care about doing the right thing and working hard',
      'They are lazy and do not care about anything',
      'They prefer to be alone at all times',
      'They are afraid of everything'
    ], 0, 'To make an inference, combine what the text says with what you already know.', 'inference', 'medium'));
    qs.push(wrQ(id++, `Think about the passage "${passage.title}." What lesson does the main character learn, or what is the most important message? Write 3-4 sentences explaining your answer. Use at least one detail from the passage to support your response.`, 'written response', 'medium'));
  } else if (grade <= 8) {
    qs.push(mcQ(id++, `What is the central theme or message of "${passage.title}"?`, [
      'Personal growth often comes from facing challenges or unfamiliar experiences',
      'Technology always makes life easier',
      'People should avoid taking risks',
      'Success depends only on luck'
    ], 0, 'Theme is the underlying message about life that the author conveys through the text.', 'theme', 'medium'));
    qs.push(mcQ(id++, 'Which type of conflict is most prominent in this passage?', [
      'Internal conflict — a character struggles with their own thoughts or feelings',
      'Character vs. nature — a character fights the weather',
      'Character vs. society — a character rebels against laws',
      'There is no conflict in this passage'
    ], 0, 'Conflict is the struggle that drives the story. Internal conflict happens within a character.', 'conflict', 'medium'));
    qs.push(mcQ(id++, 'Which sentence from the passage best supports the theme?', [
      'A sentence that shows the character learning or changing',
      'A sentence that describes the weather',
      'A sentence about what time of day it is',
      'A sentence that lists items in a room'
    ], 0, 'Text evidence is a specific quote or detail from the passage that proves your point.', 'text evidence', 'hard'));
    qs.push(saQ(id++, 'Identify one example of figurative language in the passage and explain what it means in context.', null, 'Figurative language includes simile, metaphor, personification, and imagery. Look for comparisons or descriptions that are not literal.', 'figurative language', 'hard'));
    qs.push(wrQ(id++, `How does the author develop the central idea or theme throughout "${passage.title}"? Write a paragraph that includes: (1) a clear statement of the theme, (2) at least two specific details or quotes from the passage, and (3) an explanation of how those details support the theme.`, 'text analysis', 'hard'));
    for (let i = qs.length + 1; i <= numQ; i++) {
      qs.push(mcQ(id++, 'What does the word used in the passage most likely mean based on context?', ['The meaning suggested by surrounding sentences', 'A random dictionary definition', 'The opposite of what it sounds like', 'It has no meaning'], 0, 'Context clues in surrounding sentences help determine word meaning.', 'vocabulary', 'medium'));
    }
  } else {
    qs.push(mcQ(id++, `What is the author's primary purpose in "${passage.title}"?`, [
      'To persuade the audience to think critically about the topic and take action',
      'To entertain with a lighthearted story',
      'To provide step-by-step instructions',
      'To describe a personal vacation experience'
    ], 0, "Author's purpose is the reason the author wrote the text: to inform, persuade, entertain, or express.", 'author purpose', 'medium'));
    qs.push(mcQ(id++, 'Which rhetorical appeal does the author use most effectively in this passage?', [
      'Logos — logical reasoning and evidence',
      'Only pathos — emotional appeal without any evidence',
      'Only ethos — claiming authority without supporting it',
      'The author uses no rhetorical strategies'
    ], 0, 'Rhetorical appeals include ethos (credibility), pathos (emotion), and logos (logic). Strong arguments blend multiple appeals.', 'rhetoric', 'hard'));
    qs.push(mcQ(id++, 'Which of the following best describes the tone of the passage?', [
      'Thoughtful and persuasive',
      'Angry and hostile',
      'Humorous and sarcastic',
      'Indifferent and bored'
    ], 0, 'Tone is the author\'s attitude toward the subject, revealed through word choice and style.', 'tone', 'medium'));
    qs.push(saQ(id++, 'Identify one example of figurative language or rhetorical technique in the passage. Name the device and explain its effect on the reader.', null, 'Look for metaphor, simile, parallelism, rhetorical questions, repetition, or imagery.', 'literary devices', 'hard'));
    qs.push(wrQ(id++, `Write a well-developed analytical paragraph responding to "${passage.title}." Your response should: (1) state a clear claim about the author's central argument or theme, (2) include at least two direct references to the text, (3) explain how the evidence supports your claim, and (4) consider the effectiveness of the author's approach. Use formal academic language.`, 'literary analysis', 'hard'));
    for (let i = qs.length + 1; i <= numQ; i++) {
      qs.push(mcQ(id++, 'How does the structure of the passage contribute to its effectiveness?', ['The organization builds the argument logically from evidence to conclusion', 'The random structure confuses the reader intentionally', 'There is no clear structure', 'The passage only uses bullet points'], 0, 'Authors choose structures that support their purpose: chronological, cause-effect, problem-solution, etc.', 'text structure', 'hard'));
    }
  }
  return qs.slice(0, numQ);
}

// ================================================================
// MATH CONTENT GENERATOR
// ================================================================
function mathLessonContent(lesson) {
  const grade = parseInt(lesson.grade_level);
  const t = lesson.title;
  let formula = null, concept = '', mistakes = [], steps = [];
  const rwa = `Understanding ${t} helps you solve real problems — from budgeting money and measuring ingredients to analyzing data and designing structures.`;

  if (has(t, 'add')) {
    formula = grade <= 5 ? 'a + b = sum' : null;
    concept = `Addition combines quantities to find a total. ${grade <= 5 ? 'Start at the ones place and regroup when the sum is 10 or more.' : 'Addition properties include commutative (a+b=b+a), associative ((a+b)+c=a+(b+c)), and identity (a+0=a).'}`;
    const a = rand(10*grade, 50*grade), b = rand(10*grade, 50*grade);
    steps = [{ step: `Add ${a} + ${b}`, work: `Line up by place value. Add ones, then tens. ${a%10+b%10>=10?'Regroup:':''} ${a}+${b}=${a+b}`, answer: `${a+b}` }];
    mistakes = [{ mistake: 'Forgetting to regroup (carry) when a column sums to 10 or more', correction: 'Always check if each column total is 10+. If so, write the ones digit and carry the tens digit.' }];
  } else if (has(t, 'subtract')) {
    concept = `Subtraction finds the difference between two quantities. ${grade <= 5 ? 'When the top digit is smaller, borrow from the next column.' : 'Subtraction is the inverse of addition. Check by adding: if a-b=c, then c+b=a.'}`;
    const a = rand(30*grade, 100*grade), b = rand(10, a);
    steps = [{ step: `Subtract ${a} − ${b}`, work: `Line up by place value. Subtract right to left. Borrow if needed.`, answer: `${a-b}` }];
    mistakes = [{ mistake: 'Forgetting to borrow when the top digit is smaller', correction: 'Borrow 1 from the next column (making it 10+ in the current column).' }];
  } else if (has(t, 'multipl')) {
    formula = 'a × b = product';
    concept = `Multiplication is repeated addition. ${grade <= 5 ? 'Learn times tables 1-12. Use arrays and groups to visualize.' : 'For multi-digit: multiply each digit, shift rows, add partial products. Distributive property: a(b+c) = ab+ac.'}`;
    const a = rand(3, grade<=5?12:50), b = rand(3, grade<=5?12:20);
    steps = [{ step: `Calculate ${a} × ${b}`, work: `${a} groups of ${b}: ${a}×${b}=${a*b}`, answer: `${a*b}` }];
    mistakes = [{ mistake: 'Not aligning partial products correctly in multi-digit multiplication', correction: 'Each new row shifts one place left. Then add all rows.' }];
  } else if (has(t, 'divis')) {
    concept = `Division splits a total into equal groups. ${grade <= 5 ? 'Use the DMSB method: Divide, Multiply, Subtract, Bring down.' : 'Division is the inverse of multiplication. Check: quotient × divisor + remainder = dividend.'}`;
    const d = rand(2,9), q = rand(5,20);
    steps = [{ step: `Divide ${d*q} ÷ ${d}`, work: `How many times does ${d} go into ${d*q}? ${d}×${q}=${d*q}`, answer: `${q}` }];
    mistakes = [{ mistake: 'Forgetting to include the remainder', correction: 'If division is not exact, record the remainder: quotient R remainder.' }];
  } else if (has(t, 'fract')) {
    formula = 'a/b + c/d = (ad + bc) / bd';
    concept = 'A fraction represents part of a whole. The numerator (top) shows parts selected; the denominator (bottom) shows total equal parts. To add or subtract fractions, find a common denominator first.';
    steps = [{ step: 'Add 1/4 + 2/4', work: 'Same denominator: (1+2)/4 = 3/4', answer: '3/4' }, { step: 'Add 1/3 + 1/6', work: 'LCD=6. Convert: 2/6+1/6=3/6=1/2', answer: '1/2' }];
    mistakes = [{ mistake: 'Adding denominators: 1/4+1/4≠2/8', correction: 'Only add numerators when denominators match. 1/4+1/4=2/4=1/2.' }];
  } else if (has(t, 'equation', 'variable', 'algebra', 'solve', 'expression')) {
    formula = 'To solve ax + b = c: subtract b, then divide by a';
    const a=rand(2,8), x=rand(2,10), b=rand(1,15);
    concept = `An equation states two expressions are equal. To solve, isolate the variable using inverse operations. Whatever you do to one side, do to the other.`;
    steps = [{ step: `Solve: ${a}x + ${b} = ${a*x+b}`, work: `Step 1: Subtract ${b}: ${a}x = ${a*x}. Step 2: Divide by ${a}: x = ${x}. Check: ${a}(${x})+${b}=${a*x+b} ✓`, answer: `x = ${x}` }];
    mistakes = [{ mistake: 'Performing an operation on only one side of the equation', correction: 'Always apply the same operation to BOTH sides to maintain balance.' }];
  } else if (has(t, 'geometry', 'area', 'perimeter', 'volume', 'angle', 'shape', 'triangle', 'circle')) {
    formula = 'Area of rectangle = l × w | Area of triangle = ½ × b × h | Circumference = 2πr';
    const l=rand(5,15), w=rand(3,10);
    concept = 'Geometry studies shapes, sizes, and spatial relationships. Area measures space inside a 2D shape. Volume measures space inside a 3D shape.';
    steps = [{ step: `Find area: rectangle ${l}×${w}`, work: `A = length × width = ${l} × ${w}`, answer: `${l*w} square units` }];
    mistakes = [{ mistake: 'Confusing area (square units) with perimeter (linear units)', correction: 'Area = inside space (multiply). Perimeter = outside distance (add all sides).' }];
  } else if (has(t, 'quadrat', 'polynom', 'factor')) {
    formula = 'Quadratic formula: x = (-b ± √(b²-4ac)) / 2a';
    concept = 'A quadratic equation has the form ax²+bx+c=0. Solve by factoring, completing the square, or the quadratic formula. The discriminant b²-4ac tells how many real solutions exist.';
    steps = [{ step: 'Solve x²-5x+6=0', work: 'Factor: (x-2)(x-3)=0. Set each factor=0.', answer: 'x=2 or x=3' }];
    mistakes = [{ mistake: 'Forgetting to set the equation equal to zero before factoring', correction: 'Always rearrange to standard form ax²+bx+c=0 first.' }];
  } else if (has(t, 'slope', 'linear', 'function', 'graph', 'intercept')) {
    formula = 'Slope-intercept form: y = mx + b | Slope: m = (y₂-y₁)/(x₂-x₁)';
    concept = 'A linear function produces a straight line. The slope (m) measures steepness. The y-intercept (b) is where the line crosses the y-axis.';
    steps = [{ step: 'Find slope between (1,3) and (4,9)', work: 'm=(9-3)/(4-1)=6/3=2', answer: 'm=2' }];
    mistakes = [{ mistake: 'Swapping x and y values in the slope formula', correction: 'Slope = rise/run = (y₂-y₁)/(x₂-x₁). Keep the order consistent.' }];
  } else if (has(t, 'trig', 'sin', 'cos', 'tan')) {
    formula = 'SOH CAH TOA: sin=opp/hyp, cos=adj/hyp, tan=opp/adj';
    concept = 'Trigonometry relates angles to side lengths in right triangles. The three main ratios are sine, cosine, and tangent. The unit circle extends these to all angles.';
    steps = [{ step: 'Find opposite side: angle 30°, hyp=10', work: 'sin(30°)=opp/10, opp=10×0.5=5', answer: '5' }];
    mistakes = [{ mistake: 'Using the wrong trig ratio for the given sides', correction: 'SOH CAH TOA: identify which sides you have relative to the angle.' }];
  } else {
    concept = `This lesson covers important mathematical concepts related to ${t}. Mathematics builds cumulatively—each new concept relies on understanding previous ones. Approach each problem methodically: identify what is given, determine what to find, choose a strategy, solve step by step, and verify your answer.`;
    steps = [{ step: `Apply the concepts from ${t}`, work: 'Identify given information, set up the problem, solve systematically, check your work.', answer: 'Verify by substituting back into the original problem.' }];
    mistakes = [{ mistake: 'Skipping steps and trying to solve in your head', correction: 'Show every step. This helps you catch errors and earn partial credit.' }];
  }

  return {
    concept_title: t,
    concept_explanation: concept,
    formula_text: formula,
    step_by_step_examples: JSON.stringify(steps),
    common_mistakes: JSON.stringify(mistakes),
    real_world_application: rwa,
    instructional_content: concept,
    learning_objectives: [
      `Understand the concepts and methods of ${t}.`,
      `Solve problems involving ${t} accurately.`,
      `Show work and explain reasoning step by step.`,
      `Identify and avoid common mistakes.`,
      `Apply ${t} to real-world situations.`
    ].join('\n'),
    vocabulary: JSON.stringify([
      { term: 'Expression', definition: 'A combination of numbers, variables, and operations.' },
      { term: 'Equation', definition: 'A statement that two expressions are equal.' },
      { term: 'Solution', definition: 'A value that makes an equation true.' },
      { term: 'Variable', definition: 'A letter representing an unknown value.' }
    ])
  };
}

// ================================================================
// SCIENCE CONTENT GENERATOR
// ================================================================
function scienceLessonContent(lesson) {
  const t = lesson.title, grade = parseInt(lesson.grade_level);
  let concept = '', materials = null, safety = null, expSteps = null, obsQ = null, conclusion = null, rwa = '';

  if (has(t, 'plant', 'photo', 'seed', 'flower')) {
    concept = 'Plants produce their own food through photosynthesis: 6CO₂ + 6H₂O + light → C₆H₁₂O₆ + 6O₂. Chlorophyll in chloroplasts absorbs light energy. Plants have a life cycle: seed → germination → growth → flowering → pollination → seed production.';
    materials = ['2 small pots', 'potting soil', 'bean seeds', 'water', 'ruler', 'journal'];
    safety = 'Wash hands after handling soil. Do not eat seeds or soil.';
    expSteps = [{ step: 'Plant a bean seed in each pot. Place one in sunlight, one in a dark closet.', detail: 'Water both equally. Measure and record growth daily for 2 weeks.' }];
    obsQ = ['Which plant grew taller? Why?', 'What happened to the plant without sunlight?', 'What does this tell you about what plants need?'];
    conclusion = 'Write a conclusion explaining how sunlight affects plant growth. Use your data as evidence.';
    rwa = 'Agriculture depends on understanding plant needs. Farmers optimize sunlight, water, and soil nutrients to grow food.';
  } else if (has(t, 'cell', 'organelle', 'membran', 'mitosis')) {
    concept = 'All living things are made of cells. Prokaryotic cells (bacteria) lack a nucleus. Eukaryotic cells (plants, animals) have a nucleus containing DNA. Key organelles: nucleus (control center), mitochondria (energy), ribosomes (proteins), cell membrane (boundary).';
    materials = ['microscope (optional)', 'prepared slides or diagrams', 'colored pencils', 'paper'];
    expSteps = [{ step: 'Draw and label an animal cell and a plant cell.', detail: 'Include: nucleus, cell membrane, mitochondria, ribosomes. For plant cells, add: cell wall, chloroplasts, central vacuole.' }];
    obsQ = ['What structures do plant and animal cells share?', 'What structures are unique to plant cells?', 'Why do plant cells need chloroplasts but animal cells do not?'];
    conclusion = 'Explain the relationship between cell structure and function. Why does each organelle matter?';
    rwa = 'Understanding cells is the foundation of medicine, genetics, and biotechnology.';
  } else if (has(t, 'force', 'motion', 'newton', 'gravity', 'friction')) {
    concept = 'Newton\'s Three Laws: 1st—An object stays at rest or in motion unless acted on by a force (inertia). 2nd—Force = mass × acceleration (F=ma). 3rd—Every action has an equal and opposite reaction. Friction opposes motion. Gravity accelerates objects at 9.8 m/s².';
    materials = ['toy car', 'ramp', 'ruler', 'timer', 'different surfaces (carpet, tile, sandpaper)'];
    safety = 'Keep the ramp stable. Do not stand on the ramp.';
    expSteps = [{ step: 'Release a toy car from the same height on ramps with different surfaces.', detail: 'Measure how far the car travels on each surface. Record in a data table.' }];
    obsQ = ['On which surface did the car travel farthest?', 'On which surface did it travel the shortest distance?', 'How does friction affect the car\'s motion?'];
    conclusion = 'Explain how friction affects motion using your experimental data as evidence.';
    rwa = 'Engineers design brakes, tires, and road surfaces using knowledge of friction and motion.';
  } else if (has(t, 'weather', 'climate', 'water cycle', 'atmosphere', 'cloud')) {
    concept = 'Weather is short-term atmospheric conditions. Climate is long-term averages. The water cycle: evaporation → condensation → precipitation → collection. Cloud types indicate weather: cumulus (fair), stratus (steady rain), cumulonimbus (storms).';
    materials = ['glass jar', 'hot water', 'ice', 'plate', 'food coloring (optional)'];
    expSteps = [{ step: 'Create a mini water cycle: pour hot water into a jar, place a plate with ice on top.', detail: 'Observe condensation forming on the plate. Watch droplets fall back into the jar.' }];
    obsQ = ['Where did you see evaporation?', 'Where did condensation occur?', 'What represented precipitation?'];
    conclusion = 'Explain how your model demonstrates the water cycle. How does this compare to what happens in nature?';
    rwa = 'Meteorologists use water cycle knowledge to predict weather. Climate scientists study long-term patterns.';
  } else if (has(t, 'chem', 'atom', 'element', 'molecule', 'react', 'compound', 'periodic')) {
    concept = 'All matter is made of atoms (protons, neutrons, electrons). Elements are pure substances of one atom type. The periodic table organizes elements by atomic number. Compounds form when elements bond: ionic (transfer electrons) or covalent (share electrons). Chemical equations must be balanced.';
    materials = ['baking soda', 'vinegar', 'balloon', 'empty bottle', 'safety goggles'];
    safety = 'Wear safety goggles. Do not taste chemicals. Work in a ventilated area.';
    expSteps = [{ step: 'Put 2 tablespoons of baking soda into a balloon. Pour vinegar into a bottle. Stretch the balloon over the bottle opening and lift to drop the baking soda in.', detail: 'Observe the balloon inflating. The reaction: NaHCO₃ + CH₃COOH → CO₂ + H₂O + NaCH₃COO.' }];
    obsQ = ['What gas inflated the balloon?', 'Was this a chemical or physical change? How do you know?', 'What evidence of a chemical reaction did you observe?'];
    conclusion = 'Explain what happened using the law of conservation of mass. Were atoms created or destroyed?';
    rwa = 'Chemical reactions power everything from baking bread to rocket engines to batteries.';
  } else if (has(t, 'earth', 'rock', 'mineral', 'plate', 'tectonic', 'volcano', 'earthquake')) {
    concept = 'Earth has layers: crust, mantle, outer core, inner core. Plate tectonics: Earth\'s crust is divided into moving plates. Convergent boundaries create mountains. Divergent boundaries create rifts. Transform boundaries cause earthquakes. The rock cycle: igneous → sedimentary → metamorphic (and back).';
    rwa = 'Geologists study Earth\'s structure to predict earthquakes, find resources, and understand natural hazards.';
  } else if (has(t, 'space', 'planet', 'solar', 'star', 'moon', 'orbit', 'galaxy')) {
    concept = 'Our solar system has 8 planets orbiting the Sun. Inner planets (Mercury-Mars) are rocky. Outer planets (Jupiter-Neptune) are gas/ice giants. Earth\'s rotation causes day/night. Its revolution causes years. The 23.5° axial tilt causes seasons. Stars produce energy through nuclear fusion.';
    rwa = 'Space science enables satellite communication, GPS navigation, weather forecasting, and exploration.';
  } else if (has(t, 'ecosystem', 'food chain', 'biome', 'habitat', 'environment', 'ecolog')) {
    concept = 'An ecosystem includes all living (biotic) and nonliving (abiotic) factors in an area. Energy flows: producers → primary consumers → secondary consumers → decomposers. Only ~10% of energy transfers between trophic levels. Biomes are large ecosystems defined by climate.';
    rwa = 'Ecologists study ecosystems to protect biodiversity, manage resources, and address environmental challenges.';
  } else if (has(t, 'energy', 'electric', 'circuit', 'magnet', 'wave', 'sound', 'light')) {
    concept = 'Energy is the ability to do work. Forms: kinetic, potential, thermal, electrical, chemical, light, sound. Conservation of energy: energy transforms but total amount stays constant. Circuits need a source, conductor, and load. Waves transfer energy; mechanical waves need a medium, electromagnetic waves do not.';
    rwa = 'Energy science underpins electricity, renewable power, communication technology, and medical imaging.';
  } else if (has(t, 'genet', 'dna', 'hered', 'evolut', 'natural select')) {
    concept = 'DNA stores genetic instructions in a double helix. Genes are DNA segments coding for traits. Humans have 46 chromosomes (23 pairs). Dominant alleles are expressed with one copy; recessive require two. Natural selection: organisms with favorable traits reproduce more, driving evolution over generations.';
    rwa = 'Genetics informs medicine (genetic testing, gene therapy), agriculture (crop improvement), and forensics (DNA evidence).';
  } else {
    concept = `This lesson explores scientific concepts related to ${t}. Science uses the scientific method: observe → question → hypothesize → experiment → analyze → conclude. Always record observations carefully, control variables, and base conclusions on evidence.`;
    rwa = `Understanding ${t} connects to real-world applications in technology, health, and environmental stewardship.`;
  }

  return {
    concept_title: t,
    concept_explanation: concept,
    materials_needed: materials ? JSON.stringify(materials) : null,
    safety_notes: safety,
    experiment_steps: expSteps ? JSON.stringify(expSteps) : null,
    observation_questions: obsQ ? JSON.stringify(obsQ) : null,
    conclusion_prompt: conclusion,
    real_world_application: rwa,
    instructional_content: concept,
    learning_objectives: [
      `Explain the key scientific concepts of ${t}.`,
      `Use scientific vocabulary accurately.`,
      `Apply the scientific method to investigate questions.`,
      `Analyze data and draw evidence-based conclusions.`,
      `Connect ${t} to real-world applications.`
    ].join('\n'),
    vocabulary: null // Keep existing if populated
  };
}

// ================================================================
// SOCIAL STUDIES CONTENT GENERATOR
// ================================================================
function ssLessonContent(lesson) {
  const t = lesson.title, grade = parseInt(lesson.grade_level);
  let context = '', sourceTitle = null, sourceType = null, sourceText = null, rwa = '';

  if (has(t, 'government', 'constitution', 'branch', 'democracy', 'civic', 'rights', 'law')) {
    context = 'The United States Constitution, ratified in 1788, established a federal system with three branches: legislative (Congress makes laws), executive (President enforces laws), and judicial (courts interpret laws). The Bill of Rights (first 10 amendments) protects individual freedoms. Checks and balances prevent any branch from becoming too powerful.';
    sourceTitle = 'Excerpt: The Preamble to the Constitution';
    sourceType = 'primary_source';
    sourceText = '"We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defence, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America."';
    rwa = 'Understanding government helps citizens participate in democracy through voting, civic engagement, and understanding their rights.';
  } else if (has(t, 'revolution', 'independence', 'colonial', 'civil war', 'war')) {
    context = 'Major conflicts have shaped American history. The American Revolution (1775-1783) established independence from Britain. The Civil War (1861-1865) ended slavery and preserved the Union. World Wars I and II reshaped global politics. Each conflict had complex causes, key turning points, and lasting consequences.';
    rwa = 'Studying conflicts helps us understand how nations form, how rights are won, and how to work toward peace.';
  } else if (has(t, 'geography', 'map', 'region', 'continent', 'landform')) {
    context = 'Geography studies Earth\'s physical features and human activity. Physical geography examines landforms, water systems, and climate. Human geography examines where and how people live. Maps use legends, scales, and compass roses. Latitude (horizontal) and longitude (vertical) create a coordinate system for any location on Earth.';
    rwa = 'Geographic knowledge helps with navigation, urban planning, resource management, and understanding cultural differences.';
  } else if (has(t, 'econom', 'trade', 'market', 'supply', 'demand', 'financ')) {
    context = 'Economics studies how people use limited resources. Supply and demand determine prices. Scarcity forces choices. Opportunity cost is what you give up when choosing. GDP measures national economic output. Inflation reduces purchasing power over time.';
    rwa = 'Economic literacy helps with personal budgeting, career decisions, understanding policy, and financial planning.';
  } else {
    context = `This lesson examines important social studies concepts related to ${t}. Social studies encompasses history, geography, government, economics, and culture. Understanding the past helps us make informed decisions about the present and future.`;
    rwa = `Studying ${t} develops critical thinking, civic awareness, and understanding of diverse perspectives.`;
  }

  return {
    historical_context: context,
    source_title: sourceTitle,
    source_type: sourceType,
    source_text: sourceText,
    real_world_application: rwa,
    concept_title: t,
    concept_explanation: context,
    instructional_content: context,
    learning_objectives: [
      `Explain key concepts related to ${t}.`,
      `Use historical vocabulary accurately.`,
      `Analyze causes, effects, and perspectives.`,
      `Support claims with evidence from sources.`,
      `Connect historical events to the present day.`
    ].join('\n'),
    vocabulary: null
  };
}

// ================================================================
// ELECTIVE CONTENT GENERATOR
// ================================================================
function electiveLessonContent(subject, lesson) {
  const t = lesson.title, grade = parseInt(lesson.grade_level);
  let result = {
    concept_title: t,
    instructional_content: `This lesson covers key concepts in ${subject} related to ${t}.`,
    learning_objectives: `Understand and apply concepts from ${t}.\nDevelop skills through guided practice.\nReflect on your learning.`,
    vocabulary: null, real_world_application: null
  };

  if (subject === 'Spanish' || subject === 'French') {
    const lang = subject;
    const greetings = subject === 'Spanish'
      ? { hello: 'Hola', goodbye: 'Adiós', thanks: 'Gracias', please: 'Por favor', howareyou: '¿Cómo estás?', fine: 'Bien, gracias', name: 'Me llamo...' }
      : { hello: 'Bonjour', goodbye: 'Au revoir', thanks: 'Merci', please: "S'il vous plaît", howareyou: 'Comment allez-vous?', fine: 'Bien, merci', name: "Je m'appelle..." };
    result.concept_explanation = `${lang} is spoken by hundreds of millions of people worldwide. This lesson introduces key vocabulary, grammar patterns, and conversational phrases. Practice pronunciation by reading aloud and listening to native speakers when possible.`;
    result.instructional_content = `Greetings: ${greetings.hello} (Hello), ${greetings.goodbye} (Goodbye), ${greetings.thanks} (Thank you), ${greetings.please} (Please).\n\nConversation: "${greetings.howareyou}" means "How are you?" Answer: "${greetings.fine}" (Fine, thanks). "${greetings.name}" means "My name is..."\n\nPractice saying each phrase aloud. Focus on pronunciation and natural rhythm.`;
    result.real_world_application = `${lang} is useful for travel, careers in international business, healthcare, education, and diplomacy.`;
  } else if (subject === 'Music') {
    result.concept_explanation = 'Music is organized sound. The building blocks include rhythm (beat patterns), melody (pitch sequences), harmony (simultaneous notes), and dynamics (volume). Reading music requires understanding staff notation, clefs, note values, and time signatures.';
    result.instructional_content = 'In 4/4 time: whole note=4 beats, half note=2, quarter note=1, eighth note=½. Treble clef lines: E-G-B-D-F. Treble clef spaces: F-A-C-E. Dynamics range from pianissimo (pp, very soft) to fortissimo (ff, very loud).';
    result.real_world_application = 'Music develops creativity, discipline, and cognitive skills. It is used in entertainment, therapy, education, and cultural expression.';
  } else if (subject === 'Art') {
    result.concept_explanation = 'Art uses visual elements to express ideas and emotions. The seven elements of art: line, shape, form, color, value, texture, space. The principles of design: balance, contrast, emphasis, movement, pattern, rhythm, unity.';
    result.materials_needed = JSON.stringify(['sketchbook', 'pencils', 'colored pencils or markers', 'eraser']);
    result.instructional_content = 'Color theory: Primary colors (red, blue, yellow) mix to create secondary colors (orange, green, purple). Complementary colors (opposites on the color wheel) create contrast. Value refers to lightness and darkness—use shading to create depth and form.';
    result.real_world_application = 'Art skills apply to graphic design, architecture, advertising, fashion, film, and personal expression.';
  } else if (subject === 'PE' || subject === 'Physical Education') {
    result.concept_explanation = 'Physical education develops fitness, coordination, and health knowledge. The five components of health-related fitness: cardiovascular endurance, muscular strength, muscular endurance, flexibility, and body composition.';
    result.safety_notes = 'Always warm up before exercise. Stay hydrated. Stop if you feel pain, dizziness, or shortness of breath. Use proper form to prevent injury.';
    result.instructional_content = 'Warm up (5-10 min light activity) → Main activity (20-40 min) → Cool down (5-10 min stretching). Young people need 60 minutes of moderate-to-vigorous activity daily.';
    result.real_world_application = 'Regular physical activity improves mood, sleep, academic performance, and long-term health.';
  } else if (subject === 'Technology' || subject === 'Computer Science') {
    result.concept_explanation = 'Technology literacy means understanding how to use digital tools effectively and responsibly. Core concepts include hardware vs. software, algorithms, data, networks, and cybersecurity.';
    result.safety_notes = 'Protect personal information online. Use strong unique passwords. Think before sharing. Report cyberbullying. Verify sources before trusting information.';
    result.instructional_content = 'An algorithm is a step-by-step procedure. Programs are algorithms written in code. The internet connects billions of devices through networks. Digital citizenship means using technology responsibly and ethically.';
    result.real_world_application = 'Technology skills are essential in nearly every career. Computational thinking helps solve problems in all fields.';
  } else if (subject === 'Health') {
    result.concept_explanation = 'Health encompasses physical, mental, and social well-being. Key areas: nutrition, exercise, sleep, mental health, hygiene, and disease prevention.';
    result.instructional_content = 'A balanced diet includes fruits, vegetables, whole grains, lean proteins, and healthy fats. Teens need 8-10 hours of sleep. Mental health strategies include physical activity, social connection, stress management, and seeking help when needed.';
    result.real_world_application = 'Health knowledge helps you make informed decisions about nutrition, fitness, relationships, and medical care throughout life.';
  }

  return result;
}

// ================================================================
// SUBJECT-SPECIFIC QUESTION GENERATOR
// ================================================================
function generateSubjectQuestions(subject, lesson, numQ) {
  const grade = parseInt(lesson.grade_level), t = lesson.title;
  let qs = [], id = 1;

  if (['Math', 'Mathematics'].includes(subject)) {
    if (has(t, 'add')) {
      const a=rand(10*grade,50*grade), b=rand(10*grade,50*grade);
      qs.push(saQ(id++, `Calculate: ${a} + ${b}`, `${a+b}`, 'Add by place value, regrouping as needed.', 'addition', 'medium'));
      qs.push(mcQ(id++, `What is the sum of ${a} and ${b}?`, [`${a+b}`,`${a+b+10}`,`${a+b-1}`,`${a+b+5}`], 0, `${a}+${b}=${a+b}`, 'addition', 'easy'));
      qs.push(tfQ(id++, `The commutative property means ${a}+${b} = ${b}+${a}.`, true, 'The commutative property states changing the order of addends does not change the sum.', 'properties', 'easy'));
    } else if (has(t, 'subtract')) {
      const a=rand(50*grade,200*grade), b=rand(10,a);
      qs.push(saQ(id++, `Calculate: ${a} − ${b}`, `${a-b}`, 'Subtract by place value, borrowing as needed.', 'subtraction', 'medium'));
      qs.push(mcQ(id++, `What is ${a} − ${b}?`, [`${a-b}`,`${a-b+1}`,`${a-b-2}`,`${a+b}`], 0, `${a}-${b}=${a-b}`, 'subtraction', 'easy'));
    } else if (has(t, 'multipl')) {
      const a=rand(3,12), b=rand(3,12);
      qs.push(saQ(id++, `Calculate: ${a} × ${b}`, `${a*b}`, `${a} groups of ${b}.`, 'multiplication', 'medium'));
      qs.push(mcQ(id++, `What is the product of ${a} and ${b}?`, [`${a*b}`,`${a*b+a}`,`${a*b-b}`,`${a+b}`], 0, `${a}×${b}=${a*b}`, 'multiplication', 'easy'));
    } else if (has(t, 'fract')) {
      qs.push(mcQ(id++, 'What is 1/4 + 2/4?', ['3/4','3/8','1/2','2/4'], 0, 'Same denominator: add numerators. (1+2)/4=3/4.', 'fractions', 'medium'));
      qs.push(saQ(id++, 'Simplify: 6/8', '3/4', 'Divide numerator and denominator by GCF (2): 6÷2/8÷2=3/4.', 'fractions', 'medium'));
    } else if (has(t, 'equation', 'algebra', 'solve', 'variable')) {
      qs.push(saQ(id++, 'Solve: 3x + 7 = 22', 'x = 5', 'Subtract 7: 3x=15. Divide by 3: x=5. Check: 3(5)+7=22 ✓', 'equations', 'medium'));
      qs.push(mcQ(id++, 'Solve: 2x = 16', ['x = 8','x = 4','x = 32','x = 14'], 0, 'Divide both sides by 2: x=16/2=8.', 'equations', 'easy'));
    } else if (has(t, 'geometry', 'area', 'perimeter', 'volume', 'shape', 'angle')) {
      const l=rand(5,12), w=rand(3,8);
      qs.push(saQ(id++, `Find the area of a rectangle: length=${l}, width=${w}`, `${l*w}`, `A=l×w=${l}×${w}=${l*w} sq units.`, 'area', 'medium'));
      qs.push(mcQ(id++, `Find the perimeter of a rectangle: length=${l}, width=${w}`, [`${2*(l+w)}`,`${l*w}`,`${l+w}`,`${4*l}`], 0, `P=2(l+w)=2(${l}+${w})=2(${l+w})=${2*(l+w)}`, 'perimeter', 'medium'));
    } else {
      const a=rand(10,99), b=rand(10,99);
      qs.push(saQ(id++, `Calculate: ${a} + ${b}`, `${a+b}`, 'Add systematically.', 'computation', 'medium'));
      qs.push(mcQ(id++, `Which property states a+0=a?`, ['Identity property','Commutative property','Associative property','Distributive property'], 0, 'The identity property of addition states that adding 0 to any number gives that number.', 'properties', 'easy'));
    }
    // Fill remaining
    while (qs.length < numQ) {
      const x=rand(2,20), y=rand(2,20);
      qs.push(saQ(id++, `Calculate: ${x} × ${y}`, `${x*y}`, `Multiply: ${x}×${y}=${x*y}`, 'computation', 'medium'));
    }

  } else if (subject === 'Science') {
    if (has(t, 'plant', 'photo')) {
      qs.push(mcQ(id++, 'What do plants need for photosynthesis?', ['Sunlight, water, and carbon dioxide','Soil, darkness, and oxygen','Wind, rocks, and heat','Sand and ice'], 0, 'Photosynthesis requires light energy, water from roots, and CO₂ from air.', 'photosynthesis', 'medium'));
      qs.push(saQ(id++, 'What gas do plants release during photosynthesis?', 'Oxygen', 'The products of photosynthesis are glucose and oxygen (O₂).', 'photosynthesis', 'easy'));
    } else if (has(t, 'force', 'motion', 'newton')) {
      qs.push(mcQ(id++, 'According to Newton\'s Second Law, F = ma. If mass is 10 kg and acceleration is 3 m/s², what is the force?', ['30 N','13 N','7 N','3.3 N'], 0, 'F=ma=10×3=30 N.', 'forces', 'medium'));
      qs.push(tfQ(id++, 'Friction is a force that opposes motion.', true, 'Friction acts between surfaces in contact and resists sliding.', 'friction', 'easy'));
    } else if (has(t, 'cell')) {
      qs.push(mcQ(id++, 'What organelle is called the "powerhouse of the cell"?', ['Mitochondria','Nucleus','Ribosome','Cell membrane'], 0, 'Mitochondria produce ATP through cellular respiration.', 'cell biology', 'medium'));
    } else if (has(t, 'chem', 'atom', 'element')) {
      qs.push(mcQ(id++, 'What type of bond involves sharing electrons?', ['Covalent','Ionic','Metallic','Hydrogen'], 0, 'Covalent bonds form when nonmetal atoms share electron pairs.', 'bonding', 'medium'));
    } else if (has(t, 'weather', 'water cycle')) {
      qs.push(mcQ(id++, 'What is the process of liquid water becoming water vapor called?', ['Evaporation','Condensation','Precipitation','Collection'], 0, 'Evaporation is the change from liquid to gas, driven by heat.', 'water cycle', 'easy'));
    } else {
      qs.push(mcQ(id++, 'What is the first step of the scientific method?', ['Make an observation or ask a question','Write a conclusion','Conduct the experiment','Share results'], 0, 'The scientific method begins with observation and questioning.', 'scientific method', 'easy'));
    }
    qs.push(wrQ(id++, `Based on what you learned about ${t}, describe one real-world application. Explain the science behind it in at least 3-4 sentences.`, 'application', 'medium'));
    while (qs.length < numQ) {
      qs.push(tfQ(id++, 'A hypothesis must be testable and falsifiable.', true, 'Scientific hypotheses must be testable through experiments or observations.', 'scientific method', 'easy'));
    }

  } else if (['Social Studies', 'History', 'Government', 'Economics'].includes(subject)) {
    if (has(t, 'government', 'constitution', 'branch')) {
      qs.push(mcQ(id++, 'Which branch of government makes laws?', ['Legislative (Congress)','Executive (President)','Judicial (Supreme Court)','Military'], 0, 'Congress (Senate + House) is the legislative branch that writes and passes laws.', 'government', 'medium'));
      qs.push(mcQ(id++, 'What are the first ten amendments called?', ['The Bill of Rights','The Preamble','The Articles','The Federalist Papers'], 0, 'The Bill of Rights protects individual freedoms.', 'constitution', 'easy'));
    } else if (has(t, 'revolution', 'independence', 'war')) {
      qs.push(mcQ(id++, 'What was a major cause of the American Revolution?', ['Taxation without representation','A desire to expand westward','Religious conflict','A trade dispute with France'], 0, 'Colonists protested being taxed by Parliament without having elected representatives there.', 'causes', 'medium'));
    } else if (has(t, 'geography', 'map', 'continent')) {
      qs.push(mcQ(id++, 'How many continents are there?', ['7','5','6','8'], 0, 'The seven continents: Africa, Antarctica, Asia, Australia, Europe, North America, South America.', 'geography', 'easy'));
    } else {
      qs.push(mcQ(id++, 'What is a primary source?', ['An original document from the time period studied','A textbook about history','A teacher lecture','A movie about events'], 0, 'Primary sources are original artifacts or documents from the period being studied.', 'sources', 'easy'));
    }
    qs.push(wrQ(id++, `Analyze the causes and effects related to ${t}. Write a paragraph that includes at least two specific historical details and explains their significance.`, 'historical analysis', 'medium'));
    while (qs.length < numQ) {
      qs.push(tfQ(id++, 'Understanding multiple perspectives is important when studying history.', true, 'Different groups experienced events differently. Multiple perspectives give a more complete picture.', 'perspectives', 'easy'));
    }

  } else if (subject === 'Spanish' || subject === 'French') {
    const isSpanish = subject === 'Spanish';
    qs.push(mcQ(id++, isSpanish ? 'What does "Buenos días" mean?' : 'What does "Bonjour" mean?', [isSpanish ? 'Good morning' : 'Hello / Good day', 'Goodbye', 'Thank you', 'Please'], 0, isSpanish ? '"Buenos días" is the Spanish greeting for "Good morning."' : '"Bonjour" means "Hello" or "Good day" in French.', 'greetings', 'easy'));
    qs.push(saQ(id++, isSpanish ? 'Translate to Spanish: "Thank you"' : 'Translate to French: "Thank you"', isSpanish ? 'Gracias' : 'Merci', `"Thank you" = ${isSpanish?'Gracias':'Merci'}.`, 'vocabulary', 'easy'));
    qs.push(wrQ(id++, `Write 3-4 sentences in ${subject} introducing yourself. Include your name, age, and one thing you like. Then translate each sentence to English.`, 'writing practice', 'medium'));
    while (qs.length < numQ) {
      qs.push(tfQ(id++, isSpanish ? '"Rojo" means "red" in Spanish.' : '"Bleu" means "blue" in French.', true, `Basic color vocabulary in ${subject}.`, 'vocabulary', 'easy'));
    }

  } else if (subject === 'Music') {
    qs.push(mcQ(id++, 'How many beats does a whole note receive in 4/4 time?', ['4','2','1','8'], 0, 'In 4/4 time, a whole note fills an entire measure (4 beats).', 'rhythm', 'easy'));
    qs.push(mcQ(id++, 'What does "forte" mean in music?', ['Loud','Soft','Fast','Slow'], 0, 'Forte (f) means loud. Piano (p) means soft.', 'dynamics', 'easy'));
    qs.push(wrQ(id++, `Describe what you learned about ${t} and how it relates to music performance or composition.`, 'reflection', 'medium'));
    while (qs.length < numQ) qs.push(tfQ(id++, 'A treble clef is also called a G clef.', true, 'The treble clef circles around the G line.', 'notation', 'easy'));
  } else if (subject === 'Art') {
    qs.push(mcQ(id++, 'What are the three primary colors?', ['Red, blue, yellow','Red, green, blue','Orange, purple, green','Black, white, gray'], 0, 'Primary colors cannot be mixed from other colors.', 'color theory', 'easy'));
    qs.push(wrQ(id++, `Describe the art concepts from ${t}. How would you apply them in your own artwork? Include specific techniques.`, 'reflection', 'medium'));
    while (qs.length < numQ) qs.push(tfQ(id++, 'Complementary colors are opposite each other on the color wheel.', true, 'Complementary pairs create strong contrast: red-green, blue-orange, yellow-purple.', 'color theory', 'easy'));
  } else if (subject === 'PE' || subject === 'Physical Education') {
    qs.push(mcQ(id++, 'How much daily physical activity is recommended for young people?', ['60 minutes','15 minutes','120 minutes','5 minutes'], 0, 'Health organizations recommend 60 min of moderate-to-vigorous activity daily.', 'fitness', 'easy'));
    qs.push(wrQ(id++, `Log your physical activity for today. Include: what activities you did, how long each lasted, and how you felt before and after. Reflect on how ${t} concepts apply.`, 'activity log', 'easy'));
    while (qs.length < numQ) qs.push(tfQ(id++, 'Warming up before exercise helps prevent injuries.', true, 'Warm-ups increase blood flow and prepare muscles for activity.', 'safety', 'easy'));
  } else if (subject === 'Technology' || subject === 'Computer Science') {
    qs.push(mcQ(id++, 'What does CPU stand for?', ['Central Processing Unit','Computer Personal Unit','Central Power Utility','Core Processing Unit'], 0, 'The CPU processes instructions and is the "brain" of the computer.', 'hardware', 'easy'));
    qs.push(wrQ(id++, `Explain the technology concepts from ${t} and describe a practical application. How does this technology affect daily life?`, 'application', 'medium'));
    while (qs.length < numQ) qs.push(tfQ(id++, 'A strong password should include letters, numbers, and special characters.', true, 'Complex passwords are harder to guess or crack.', 'cybersecurity', 'easy'));
  } else if (subject === 'Health') {
    qs.push(mcQ(id++, 'How many hours of sleep do teenagers typically need?', ['8-10 hours','4-5 hours','12-14 hours','3 hours'], 0, 'Teens need 8-10 hours for proper growth, cognitive function, and mental health.', 'sleep', 'easy'));
    qs.push(wrQ(id++, `Discuss the health concepts from ${t}. How do they apply to your daily life? Include at least two specific examples.`, 'reflection', 'medium'));
    while (qs.length < numQ) qs.push(tfQ(id++, 'Regular hand washing helps prevent the spread of illness.', true, 'Hand washing removes germs that cause colds, flu, and other infections.', 'hygiene', 'easy'));
  } else {
    qs.push(mcQ(id++, `Which concept is most relevant to ${t}?`, ['The main concept discussed in the lesson','An unrelated topic','Something from a different subject','None of the above'], 0, 'Focus on the key concept presented in the lesson.', 'comprehension', 'easy'));
    qs.push(wrQ(id++, `Summarize the key concepts from ${t}. Include at least two specific details from the lesson and explain why they are important.`, 'summary', 'medium'));
    while (qs.length < numQ) qs.push(tfQ(id++, `The concepts in ${t} connect to real-world applications.`, true, 'Most academic concepts have practical applications.', 'application', 'easy'));
  }

  return qs.slice(0, numQ);
}

// ================================================================
// MAIN EXECUTION
// ================================================================
async function main() {
  console.log('============================================');
  console.log('JNM Home Education Program');
  console.log('Curriculum Passages Seed Script');
  console.log('============================================\n');

  const needsVideoReview = [];
  const videoBySubject = {};
  let stats = { total: 0, ela: 0, math: 0, science: 0, ss: 0, elective: 0, videosAssigned: 0, questionsUpdated: 0, errors: 0 };

  try {
    // Step 1: Add columns
    console.log('Step 1: Adding content columns to lessons table...');
    for (const col of NEW_COLUMNS) {
      const [name, ...typeParts] = col.split(' ');
      const type = typeParts.join(' ');
      await pool.query(`ALTER TABLE lessons ADD COLUMN IF NOT EXISTS ${name} ${type}`);
    }
    console.log(`  ✓ ${NEW_COLUMNS.length} columns verified\n`);

    // Step 2: Fetch all lessons
    console.log('Step 2: Fetching all lessons...');
    const result = await pool.query(`
      SELECT l.id, l.title, l.lesson_number, l.video_url,
             u.title as unit_title, u.unit_number, u.id as unit_id,
             c.name as course_name, c.subject, c.grade_level, c.id as course_id
      FROM lessons l JOIN units u ON l.unit_id = u.id JOIN courses c ON u.course_id = c.id
      ORDER BY c.grade_level, c.subject, u.unit_number, l.lesson_number
    `);
    console.log(`  ✓ Found ${result.rows.length} lessons\n`);

    // Step 3: Process each lesson
    console.log('Step 3: Generating subject-specific content...');
    let currentSubject = '';

    for (const lesson of result.rows) {
      try {
        const subject = lesson.subject;
        const isELA = ['Language Arts', 'English', 'ELA'].includes(subject);
        const isMath = ['Math', 'Mathematics'].includes(subject);
        const isScience = subject === 'Science';
        const isSS = ['Social Studies', 'History', 'Government', 'Economics'].includes(subject);

        if (subject !== currentSubject) {
          currentSubject = subject;
          console.log(`  Processing: Grade ${lesson.grade_level} ${subject}...`);
        }

        // Generate content based on subject
        let content = {};
        if (isELA) { content = elaLessonContent(lesson); stats.ela++; }
        else if (isMath) { content = mathLessonContent(lesson); stats.math++; }
        else if (isScience) { content = scienceLessonContent(lesson); stats.science++; }
        else if (isSS) { content = ssLessonContent(lesson); stats.ss++; }
        else { content = electiveLessonContent(subject, lesson); stats.elective++; }

        // Assign verified video
        const video = findVideo(subject, parseInt(lesson.grade_level), lesson.title);
        let videoUrl = null, videoSource = null, videoVerified = false, videoTitle = null;
        if (video) {
          videoUrl = video.url; videoSource = video.source; videoVerified = video.verified; videoTitle = video.title;
          stats.videosAssigned++;
          videoBySubject[subject] = (videoBySubject[subject] || 0) + 1;
        } else {
          needsVideoReview.push(`Grade ${lesson.grade_level} ${subject}: ${lesson.title}`);
          if (!videoBySubject[subject + '_missing']) videoBySubject[subject + '_missing'] = 0;
          videoBySubject[subject + '_missing']++;
        }

        // Build UPDATE query dynamically
        const fields = {
          grade_band: gradeBand(parseInt(lesson.grade_level)),
          reading_level: `Grade ${lesson.grade_level}`,
          video_url: videoUrl,
          video_source: videoSource,
          video_verified: videoVerified,
          video_title: videoTitle,
        };
        // Add all content fields that are not null/undefined
        const contentFields = ['passage_title','passage_type','reading_passage','passage_source',
          'concept_title','concept_explanation','formula_text','step_by_step_examples','common_mistakes',
          'materials_needed','safety_notes','experiment_steps','observation_questions','conclusion_prompt',
          'source_title','source_type','source_text','historical_context','real_world_application',
          'instructional_content','learning_objectives','vocabulary'];

        for (const f of contentFields) {
          if (content[f] !== undefined) fields[f] = content[f];
        }

        const setClauses = [];
        const values = [];
        let paramIdx = 1;
        for (const [key, val] of Object.entries(fields)) {
          if (val !== undefined) {
            setClauses.push(`${key} = $${paramIdx}`);
            values.push(val);
            paramIdx++;
          }
        }
        values.push(lesson.id);
        await pool.query(`UPDATE lessons SET ${setClauses.join(', ')} WHERE id = $${paramIdx}`, values);

        // Update assignment questions
        const numQ = { homework: 5, practice: 5, quiz: 8, test: 12, unit_test: 15, midterm: 20, final: 25, project: 3 };
        const assignments = await pool.query(
          'SELECT id, weight_category FROM assignments WHERE lesson_id = $1 AND is_active = true', [lesson.id]
        );
        for (const a of assignments.rows) {
          const count = numQ[a.weight_category] || 5;
          let questions;
          if (isELA) {
            const bank = parseInt(lesson.grade_level) <= 5 ? ELA_ELEMENTARY : parseInt(lesson.grade_level) <= 8 ? ELA_MIDDLE : ELA_HIGH;
            let passage = bank.find(p => p.keywords.some(k => has(lesson.title, k)));
            if (!passage) passage = bank[Math.abs(hashCode(lesson.title)) % bank.length];
            questions = elaQuestions(lesson, passage, count);
          } else {
            questions = generateSubjectQuestions(subject, lesson, count);
          }
          await pool.query('UPDATE assignments SET questions = $1 WHERE id = $2', [JSON.stringify(questions), a.id]);
          stats.questionsUpdated++;
        }

        stats.total++;
      } catch (err) {
        stats.errors++;
        console.error(`  ✗ Error on lesson ${lesson.id} (${lesson.title}): ${err.message}`);
      }
    }

    // Summary
    console.log(`\n============================================`);
    console.log('CURRICULUM SEED COMPLETE');
    console.log('============================================');
    console.log(`Total lessons processed: ${stats.total}`);
    console.log(`  ELA: ${stats.ela}`);
    console.log(`  Math: ${stats.math}`);
    console.log(`  Science: ${stats.science}`);
    console.log(`  Social Studies: ${stats.ss}`);
    console.log(`  Electives: ${stats.elective}`);
    console.log(`  Videos assigned: ${stats.videosAssigned}`);
    console.log(`  Assignment questions updated: ${stats.questionsUpdated}`);
    console.log(`  Errors: ${stats.errors}`);
    console.log(`\nLessons needing video review: ${needsVideoReview.length}`);
    console.log('\nVideo Audit by Subject:');
    const allSubjects = new Set([...Object.keys(videoBySubject).map(k => k.replace('_missing', ''))]);
    for (const subj of allSubjects) {
      const added = videoBySubject[subj] || 0;
      const missing = videoBySubject[subj + '_missing'] || 0;
      const status = missing === 0 ? '✓ COMPLETE' : added > 0 ? '⚠ PARTIAL' : '✗ NONE';
      console.log(`  ${subj}: ${added} added / ${missing} missing ${status}`);
    }
    if (needsVideoReview.length > 0 && needsVideoReview.length <= 20) {
      needsVideoReview.forEach(l => console.log(`  - ${l}`));
    } else if (needsVideoReview.length > 20) {
      needsVideoReview.slice(0, 20).forEach(l => console.log(`  - ${l}`));
      console.log(`  ... and ${needsVideoReview.length - 20} more`);
    }
    console.log('============================================');

  } catch (err) {
    console.error('Fatal error:', err);
  } finally {
    await pool.end();
  }
}

main();
