// ================================================================
// JNM Home Education Program — Kindergarten Seed (REAL, not a demo)
// ================================================================
// Run:  node seed-kindergarten.js
//
// PREREQUISITES:
//   - migration-phase2.sql has been run (adds lesson media columns,
//     skill_progress + time_logs tables)
//
// BACKUP FIRST:  pg_dump jnm_homeschool_db > backup_before_k.sql
//
// Creates a REAL functioning Kindergarten section (grade_level = 0):
//   Courses: Reading & Phonics, Kindergarten Math, Science & Discovery,
//            Art & Music, Movement & Play
//   Each course -> units -> lessons (which ARE the K activities).
//   Lessons carry: lesson_type, interactive_type, image_url (topic-matched
//   inline SVG), audio_url placeholder, activity_data (cards/choices/story),
//   and skill_name. Kindergarten is skill-based, NOT percentage-graded.
//
// Topic-matched visuals: each lesson gets a simple, clearly-labeled inline
// SVG that matches its topic (apple, cat, circle, the letter A, sun, etc.).
// These are real, deterministic images embedded as data URIs — never random.
// Replace image_url with real photos later if desired.
// ================================================================

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'
});

// ----------------------------------------------------------------
// TOPIC-MATCHED VISUALS (inline SVG data URIs — deterministic, safe)
// Each returns a small kid-friendly SVG that matches the topic.
// ----------------------------------------------------------------
function svg(inner, bg) {
  const s = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">` +
    `<rect width="200" height="200" rx="20" fill="${bg || '#FFF7E6'}"/>` + inner + `</svg>`;
  return 'data:image/svg+xml;utf8,' + encodeURIComponent(s);
}

const VISUALS = {
  apple: () => svg(`<circle cx="100" cy="115" r="55" fill="#E53935"/><rect x="96" y="45" width="8" height="30" rx="4" fill="#6D4C41"/><path d="M104 55 q25 -15 35 5 q-25 5 -35 -5z" fill="#4CAF50"/>`),
  cat: () => svg(`<circle cx="100" cy="110" r="50" fill="#FFB74D"/><polygon points="60,75 70,40 95,65" fill="#FFB74D"/><polygon points="140,75 130,40 105,65" fill="#FFB74D"/><circle cx="85" cy="105" r="7" fill="#222"/><circle cx="115" cy="105" r="7" fill="#222"/><path d="M90 125 q10 8 20 0" stroke="#222" stroke-width="3" fill="none"/><line x1="55" y1="120" x2="80" y2="123" stroke="#222" stroke-width="2"/><line x1="145" y1="120" x2="120" y2="123" stroke="#222" stroke-width="2"/>`, '#E3F2FD'),
  dog: () => svg(`<ellipse cx="100" cy="115" rx="48" ry="45" fill="#A1887F"/><ellipse cx="62" cy="95" rx="16" ry="30" fill="#8D6E63"/><ellipse cx="138" cy="95" rx="16" ry="30" fill="#8D6E63"/><circle cx="86" cy="108" r="6" fill="#222"/><circle cx="114" cy="108" r="6" fill="#222"/><ellipse cx="100" cy="128" rx="10" ry="7" fill="#222"/>`, '#E8F5E9'),
  fish: () => svg(`<ellipse cx="95" cy="110" rx="55" ry="32" fill="#29B6F6"/><polygon points="150,110 185,85 185,135" fill="#0288D1"/><circle cx="70" cy="103" r="7" fill="#fff"/><circle cx="70" cy="103" r="3" fill="#222"/>`, '#E1F5FE'),
  sun: () => svg(`<circle cx="100" cy="100" r="45" fill="#FFD54F"/>${Array.from({length:8}).map((_,i)=>{const a=i*Math.PI/4;const x1=100+Math.cos(a)*55,y1=100+Math.sin(a)*55,x2=100+Math.cos(a)*75,y2=100+Math.sin(a)*75;return `<line x1="${x1.toFixed(0)}" y1="${y1.toFixed(0)}" x2="${x2.toFixed(0)}" y2="${y2.toFixed(0)}" stroke="#FFB300" stroke-width="6" stroke-linecap="round"/>`;}).join('')}`, '#E3F2FD'),
  rain: () => svg(`<ellipse cx="100" cy="80" rx="55" ry="30" fill="#B0BEC5"/><ellipse cx="70" cy="85" rx="30" ry="22" fill="#CFD8DC"/><ellipse cx="130" cy="85" rx="30" ry="22" fill="#CFD8DC"/>${[70,100,130].map(x=>`<line x1="${x}" y1="120" x2="${x-8}" y2="150" stroke="#42A5F5" stroke-width="5" stroke-linecap="round"/>`).join('')}`, '#ECEFF1'),
  cloud: () => svg(`<ellipse cx="100" cy="105" rx="55" ry="30" fill="#ECEFF1"/><ellipse cx="72" cy="110" rx="30" ry="22" fill="#fff"/><ellipse cx="128" cy="110" rx="30" ry="22" fill="#fff"/>`, '#E3F2FD'),
  snow: () => svg(`<circle cx="100" cy="100" r="6" fill="#90CAF9"/>${Array.from({length:6}).map((_,i)=>{const a=i*Math.PI/3;const x=100+Math.cos(a)*45,y=100+Math.sin(a)*45;return `<line x1="100" y1="100" x2="${x.toFixed(0)}" y2="${y.toFixed(0)}" stroke="#64B5F6" stroke-width="5" stroke-linecap="round"/>`;}).join('')}`, '#E3F2FD'),
  tree: () => svg(`<rect x="92" y="110" width="16" height="50" fill="#8D6E63"/><circle cx="100" cy="90" r="42" fill="#66BB6A"/>`, '#E8F5E9'),
  flower: () => svg(`${Array.from({length:6}).map((_,i)=>{const a=i*Math.PI/3;const x=100+Math.cos(a)*28,y=95+Math.sin(a)*28;return `<circle cx="${x.toFixed(0)}" cy="${y.toFixed(0)}" r="18" fill="#EC407A"/>`;}).join('')}<circle cx="100" cy="95" r="16" fill="#FFD54F"/><rect x="97" y="110" width="6" height="55" fill="#43A047"/>`, '#FCE4EC'),
  circle: () => svg(`<circle cx="100" cy="100" r="55" fill="#42A5F5"/>`),
  square: () => svg(`<rect x="50" y="50" width="100" height="100" rx="6" fill="#66BB6A"/>`),
  triangle: () => svg(`<polygon points="100,45 155,150 45,150" fill="#FFA726"/>`),
  rectangle: () => svg(`<rect x="40" y="65" width="120" height="70" rx="6" fill="#AB47BC"/>`),
  star: () => svg(`<polygon points="100,40 116,85 165,85 126,113 140,160 100,132 60,160 74,113 35,85 84,85" fill="#FFCA28"/>`),
  letter: (L) => svg(`<text x="100" y="135" font-size="120" font-family="Arial" font-weight="bold" text-anchor="middle" fill="#5E35B1">${L}</text>`),
  number: (N) => svg(`<text x="100" y="140" font-size="120" font-family="Arial" font-weight="bold" text-anchor="middle" fill="#1E88E5">${N}</text>`),
  count: (n, color) => svg(Array.from({length:n}).map((_,i)=>{const cols=Math.min(n,5);const cx=40+(i%cols)*30;const cy=70+Math.floor(i/cols)*40;return `<circle cx="${cx}" cy="${cy}" r="13" fill="${color||'#EF5350'}"/>`;}).join('')),
  color: (hex, name) => svg(`<rect x="45" y="45" width="110" height="110" rx="16" fill="${hex}"/><text x="100" y="180" font-size="20" font-family="Arial" text-anchor="middle" fill="#333">${name}</text>`),
  ball: () => svg(`<circle cx="100" cy="100" r="50" fill="#FF7043"/><path d="M55 90 q45 -20 90 0" stroke="#fff" stroke-width="3" fill="none"/><path d="M55 110 q45 20 90 0" stroke="#fff" stroke-width="3" fill="none"/>`, '#E0F7FA'),
  music: () => svg(`<circle cx="80" cy="140" r="16" fill="#7E57C2"/><circle cx="140" cy="125" r="16" fill="#7E57C2"/><rect x="93" y="60" width="6" height="82" fill="#7E57C2"/><rect x="153" y="45" width="6" height="82" fill="#7E57C2"/><rect x="93" y="60" width="66" height="10" fill="#7E57C2"/>`, '#F3E5F5'),
  paint: () => svg(`<ellipse cx="100" cy="120" rx="60" ry="40" fill="#FFE0B2"/><circle cx="78" cy="115" r="12" fill="#E53935"/><circle cx="105" cy="108" r="12" fill="#43A047"/><circle cx="128" cy="120" r="12" fill="#1E88E5"/><rect x="150" y="60" width="8" height="70" fill="#6D4C41" transform="rotate(20 154 95)"/>`, '#FFFDE7'),
  bird: () => svg(`<circle cx="95" cy="105" r="38" fill="#26C6DA"/><circle cx="120" cy="95" r="22" fill="#26C6DA"/><polygon points="140,95 165,90 145,105" fill="#FFA726"/><circle cx="125" cy="90" r="4" fill="#222"/><polygon points="70,110 45,120 75,128" fill="#0097A7"/>`, '#E0F7FA'),
  stretchKid: () => svg(`<circle cx="100" cy="50" r="18" fill="#FFD3B6"/><line x1="100" y1="68" x2="100" y2="122" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="78" x2="65" y2="38" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="78" x2="135" y2="38" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="122" x2="78" y2="165" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="122" x2="122" y2="165" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><path d="M55 32 L67 40 L58 48" fill="none" stroke="#66BB6A" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M145 32 L133 40 L142 48" fill="none" stroke="#66BB6A" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>`, '#FFF8E6'),
  toeTouch: () => svg(`<circle cx="110" cy="55" r="18" fill="#FFD3B6"/><path d="M108 72 C104 96 96 112 82 126" fill="none" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="88" y1="92" x2="130" y2="106" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="84" y1="126" x2="56" y2="163" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="84" y1="126" x2="122" y2="165" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><circle cx="55" cy="164" r="8" fill="#FFB74D"/><circle cx="122" cy="166" r="8" fill="#FFB74D"/><path d="M150 70 Q138 100 116 120" fill="none" stroke="#FFCA28" stroke-width="6" stroke-linecap="round"/><polygon points="112,113 110,126 123,122" fill="#FFCA28"/>`, '#FFF8E6'),
  frogJump: () => svg(`<ellipse cx="100" cy="118" rx="42" ry="32" fill="#66BB6A"/><circle cx="82" cy="84" r="15" fill="#66BB6A"/><circle cx="118" cy="84" r="15" fill="#66BB6A"/><circle cx="82" cy="84" r="7" fill="#fff"/><circle cx="118" cy="84" r="7" fill="#fff"/><circle cx="82" cy="84" r="3" fill="#222"/><circle cx="118" cy="84" r="3" fill="#222"/><path d="M86 128 Q100 140 114 128" stroke="#2E7D32" stroke-width="4" fill="none"/><path d="M58 120 Q40 98 46 78" fill="none" stroke="#FFA726" stroke-width="6" stroke-linecap="round"/><polygon points="42,79 48,66 55,78" fill="#FFA726"/><path d="M142 120 Q160 98 154 78" fill="none" stroke="#FFA726" stroke-width="6" stroke-linecap="round"/><polygon points="158,79 152,66 145,78" fill="#FFA726"/>`, '#E8F5E9'),
  marchKid: () => svg(`<circle cx="100" cy="48" r="18" fill="#FFD3B6"/><line x1="100" y1="66" x2="100" y2="120" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="82" x2="70" y2="98" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="82" x2="130" y2="70" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="120" x2="78" y2="162" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="120" x2="130" y2="95" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><path d="M50 126 q16 -12 32 0" stroke="#26A69A" stroke-width="6" fill="none" stroke-linecap="round"/><path d="M128 82 q14 -12 28 0" stroke="#26A69A" stroke-width="6" fill="none" stroke-linecap="round"/>`, '#FFF8E6'),
  balanceKid: () => svg(`<circle cx="100" cy="48" r="18" fill="#FFD3B6"/><line x1="100" y1="66" x2="100" y2="120" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="80" x2="62" y2="90" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="80" x2="138" y2="90" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="120" x2="82" y2="165" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="120" x2="138" y2="132" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="138" y1="132" x2="155" y2="104" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><path d="M52 96 L65 84 L74 98" fill="#FFCA28"/><path d="M146 86 L160 74 L168 88" fill="#FFCA28"/>`, '#FFF8E6'),
  tossBall: () => svg(`<circle cx="70" cy="56" r="16" fill="#FFD3B6"/><line x1="70" y1="72" x2="70" y2="120" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="70" y1="86" x2="105" y2="70" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="70" y1="86" x2="48" y2="100" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="70" y1="120" x2="48" y2="164" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="70" y1="120" x2="92" y2="164" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><circle cx="130" cy="54" r="20" fill="#FF7043"/><path d="M84 80 Q104 32 130 54" fill="none" stroke="#FFA726" stroke-width="6" stroke-dasharray="8 8" stroke-linecap="round"/>`, '#E0F7FA'),
  bunnyHop: () => svg(`<ellipse cx="100" cy="115" rx="46" ry="34" fill="#F5F5F5" stroke="#DDD" stroke-width="2"/><ellipse cx="72" cy="72" rx="10" ry="28" fill="#F5F5F5" stroke="#DDD" stroke-width="2" transform="rotate(-12 72 72)"/><ellipse cx="92" cy="68" rx="10" ry="28" fill="#F5F5F5" stroke="#DDD" stroke-width="2" transform="rotate(8 92 68)"/><circle cx="108" cy="100" r="5" fill="#222"/><circle cx="124" cy="116" r="5" fill="#FFB6C1"/><path d="M42 116 Q30 92 42 74" fill="none" stroke="#FFA726" stroke-width="6" stroke-linecap="round"/><polygon points="38,75 44,62 50,75" fill="#FFA726"/>`, '#FFF8E6'),
  clapStep: () => svg(`<circle cx="84" cy="52" r="16" fill="#FFD3B6"/><line x1="84" y1="68" x2="84" y2="118" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="84" y1="82" x2="60" y2="96" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="84" y1="82" x2="112" y2="92" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="84" y1="118" x2="68" y2="162" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="84" y1="118" x2="108" y2="140" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><path d="M116 76 l12 -8 M116 90 l14 0 M116 104 l12 8" stroke="#FF7043" stroke-width="5" stroke-linecap="round"/><path d="M132 126 q10 12 24 0" stroke="#66BB6A" stroke-width="6" fill="none" stroke-linecap="round"/>`, '#F3E5F5'),
  freezeDance: () => svg(`<circle cx="100" cy="48" r="18" fill="#FFD3B6"/><line x1="100" y1="66" x2="100" y2="120" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="84" x2="66" y2="70" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="84" x2="136" y2="64" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="120" x2="72" y2="164" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><line x1="100" y1="120" x2="132" y2="150" stroke="#5C6BC0" stroke-width="10" stroke-linecap="round"/><circle cx="150" cy="62" r="24" fill="#EF5350"/><text x="150" y="69" font-size="20" font-family="Arial" font-weight="bold" text-anchor="middle" fill="#fff">STOP</text><path d="M44 68 q6 -18 18 -8" stroke="#7E57C2" stroke-width="5" fill="none"/><path d="M58 58 v20" stroke="#7E57C2" stroke-width="5"/>`, '#FFF8E6'),
  fastSlow: () => svg(`<circle cx="58" cy="132" r="18" fill="#8BC34A"/><circle cx="74" cy="124" r="14" fill="#8BC34A"/><path d="M86 124 q10 4 18 0" stroke="#8BC34A" stroke-width="6" fill="none" stroke-linecap="round"/><text x="62" y="170" font-size="20" font-family="Arial" font-weight="bold" text-anchor="middle" fill="#4E342E">Slow</text><polygon points="126,72 108,118 134,118 118,162 166,104 138,104 154,72" fill="#FFCA28" stroke="#F9A825" stroke-width="3"/><text x="140" y="170" font-size="20" font-family="Arial" font-weight="bold" text-anchor="middle" fill="#4E342E">Fast</text>`, '#FFF8E6'),
  generic: (label) => svg(`<circle cx="100" cy="90" r="45" fill="#90CAF9"/><text x="100" y="170" font-size="18" font-family="Arial" text-anchor="middle" fill="#333">${label||''}</text>`)
};

// Audio placeholder convention (no real audio file yet — clearly marked)
function audioPlaceholder(text) {
  return 'tts-placeholder:' + encodeURIComponent(text);
}

// ----------------------------------------------------------------
// KINDERGARTEN CURRICULUM DATA
// Each course: { name, subject, units: [ { title, lessons: [...] } ] }
// Each lesson: { title, lesson_type, interactive_type, skill_name,
//                image, audio, activity_data, instructional }
// ----------------------------------------------------------------
const K = [
  {
    name: 'Reading & Phonics (Kindergarten)',
    subject: 'Reading',
    description: 'Letters, sounds, sight words, and read-along stories for early readers.',
    units: [
      {
        title: 'Letters A–E',
        lessons: [
          { title: 'The Letter A', lesson_type: 'letter', interactive_type: 'tap_select', skill_name: 'Recognizes letter A',
            image: VISUALS.letter('A'), audio: audioPlaceholder('This is the letter A. A says ah, like apple. Tap the letter A.'),
            instructional: 'This is the letter A. A says "ah" like in apple. Can you find the letter A?',
            activity: { kind: 'tap_select', prompt: 'Tap the letter A', choices: [
              { label: 'A', image: VISUALS.letter('A'), correct: true },
              { label: 'B', image: VISUALS.letter('B'), correct: false },
              { label: 'C', image: VISUALS.letter('C'), correct: false } ] } },
          { title: 'Letter A Sound', lesson_type: 'letter', interactive_type: 'tap_select', skill_name: 'Knows letter A sound',
            image: VISUALS.apple(), audio: audioPlaceholder('Apple starts with A. Which one starts with A?'),
            instructional: 'A says "ah". Apple starts with A! Which picture starts with A?',
            activity: { kind: 'tap_select', prompt: 'Which one starts with A?', choices: [
              { label: 'Apple', image: VISUALS.apple(), correct: true },
              { label: 'Cat', image: VISUALS.cat(), correct: false },
              { label: 'Sun', image: VISUALS.sun(), correct: false } ] } },
          { title: 'The Letter B', lesson_type: 'letter', interactive_type: 'tap_select', skill_name: 'Recognizes letter B',
            image: VISUALS.letter('B'), audio: audioPlaceholder('This is the letter B. B says buh, like ball. Tap the letter B.'),
            instructional: 'This is the letter B. B says "buh" like in ball. Tap the letter B!',
            activity: { kind: 'tap_select', prompt: 'Tap the letter B', choices: [
              { label: 'B', image: VISUALS.letter('B'), correct: true },
              { label: 'A', image: VISUALS.letter('A'), correct: false },
              { label: 'D', image: VISUALS.letter('D'), correct: false } ] } },
          { title: 'Letter B Sound', lesson_type: 'letter', interactive_type: 'tap_select', skill_name: 'Identifies beginning sound B',
            image: VISUALS.tossBall(), audio: audioPlaceholder('Ball starts with B. Which one starts with B?'),
            instructional: 'B says "buh". Ball starts with B! Which picture starts with B?',
            activity: { kind: 'tap_select', prompt: 'Which one starts with B?', choices: [
              { label: 'Ball', image: VISUALS.tossBall(), correct: true },
              { label: 'Apple', image: VISUALS.apple(), correct: false },
              { label: 'Fish', image: VISUALS.fish(), correct: false } ] } },
          { title: 'The Letter C', lesson_type: 'letter', interactive_type: 'tap_select', skill_name: 'Recognizes letter C',
            image: VISUALS.letter('C'), audio: audioPlaceholder('This is the letter C. C says kuh, like cat. Tap the letter C.'),
            instructional: 'This is the letter C. C says "kuh" like in cat. Tap the letter C!',
            activity: { kind: 'tap_select', prompt: 'Tap the letter C', choices: [
              { label: 'C', image: VISUALS.letter('C'), correct: true },
              { label: 'O', image: VISUALS.letter('O'), correct: false },
              { label: 'B', image: VISUALS.letter('B'), correct: false } ] } }
        ]
      },
      {
        title: 'First Sight Words',
        lessons: [
          { title: 'Sight Word: the', lesson_type: 'sight_word', interactive_type: 'flip_card', skill_name: 'Recognizes sight word "the"',
            image: VISUALS.generic('the'), audio: audioPlaceholder('This sight word is the. Say the. The cat. The sun. The ball.'),
            instructional: 'This word is "the". We see it in many sentences. Flip the card and say it!',
            activity: { kind: 'flip_card', front: 'the', back: 'We say: "the"', example: 'the cat, the sun, the ball' } },
          { title: 'Sight Word: I', lesson_type: 'sight_word', interactive_type: 'flip_card', skill_name: 'Recognizes sight word "I"',
            image: VISUALS.generic('I'), audio: audioPlaceholder('This sight word is I. Say I. I see. I can. I am.'),
            instructional: 'This word is "I". We use it to talk about ourselves. Flip and say it!',
            activity: { kind: 'flip_card', front: 'I', back: 'We say: "I"', example: 'I see. I can. I am.' } },
          { title: 'Sight Word: see', lesson_type: 'sight_word', interactive_type: 'flip_card', skill_name: 'Recognizes sight word "see"',
            image: VISUALS.generic('see'), audio: audioPlaceholder('This sight word is see. Say see. I see a cat.'),
            instructional: 'This word is "see". It means to look. Flip and say it!',
            activity: { kind: 'flip_card', front: 'see', back: 'We say: "see"', example: 'I see a cat.' } }
        ]
      },
      {
        title: 'Read-Along Stories',
        lessons: [
          { title: 'Read-Along: I See a Cat', lesson_type: 'read_along', interactive_type: 'read_along', skill_name: 'Follows along with read-aloud story',
            image: VISUALS.cat(), audio: audioPlaceholder('I see a cat. The cat is happy.'),
            instructional: 'Listen and follow along. Touch each word as you hear it.',
            activity: { kind: 'read_along', title: 'I See a Cat',
              pages: [
                { text: 'I see a cat.', words: ['I','see','a','cat.'], image: VISUALS.cat(), audio: audioPlaceholder('I see a cat.') },
                { text: 'The cat is happy.', words: ['The','cat','is','happy.'], image: VISUALS.cat(), audio: audioPlaceholder('The cat is happy.') },
                { text: 'I like the cat!', words: ['I','like','the','cat!'], image: VISUALS.cat(), audio: audioPlaceholder('I like the cat!') }
              ] } },
          { title: 'Read-Along: The Sun', lesson_type: 'read_along', interactive_type: 'read_along', skill_name: 'Follows along with read-aloud story',
            image: VISUALS.sun(), audio: audioPlaceholder('I see the sun. The sun is hot.'),
            instructional: 'Listen and follow along. Touch each word as you hear it.',
            activity: { kind: 'read_along', title: 'The Sun',
              pages: [
                { text: 'I see the sun.', words: ['I','see','the','sun.'], image: VISUALS.sun(), audio: audioPlaceholder('I see the sun.') },
                { text: 'The sun is hot.', words: ['The','sun','is','hot.'], image: VISUALS.sun(), audio: audioPlaceholder('The sun is hot.') }
              ] } }
        ]
      }
    ]
  },
  {
    name: 'Kindergarten Math',
    subject: 'Math',
    description: 'Counting, number recognition, shapes, and simple patterns.',
    units: [
      {
        title: 'Counting to 10',
        lessons: [
          { title: 'Count to 5', lesson_type: 'counting', interactive_type: 'tap_select', skill_name: 'Counts to 5',
            image: VISUALS.count(5), audio: audioPlaceholder('1 2 3 4 5'),
            instructional: 'Let\'s count: 1, 2, 3, 4, 5! How many dots do you see?',
            activity: { kind: 'tap_select', prompt: 'How many dots?', choices: [
              { label: '5 dots', image: VISUALS.count(5), correct: true },
              { label: '3 dots', image: VISUALS.count(3), correct: false },
              { label: '8 dots', image: VISUALS.count(8), correct: false } ] } },
          { title: 'Count to 10', lesson_type: 'counting', interactive_type: 'tap_select', skill_name: 'Counts to 10',
            image: VISUALS.count(10, '#42A5F5'), audio: audioPlaceholder('1 2 3 4 5 6 7 8 9 10'),
            instructional: 'Let\'s count all the way to 10! Count each dot out loud.',
            activity: { kind: 'tap_select', prompt: 'How many dots?', choices: [
              { label: '10 dots', image: VISUALS.count(10, '#42A5F5'), correct: true },
              { label: '6 dots', image: VISUALS.count(6, '#42A5F5'), correct: false },
              { label: '9 dots', image: VISUALS.count(9, '#42A5F5'), correct: false } ] } }
        ]
      },
      {
        title: 'Numbers 1–5',
        lessons: [
          { title: 'Number 1', lesson_type: 'number', interactive_type: 'tap_select', skill_name: 'Recognizes number 1',
            image: VISUALS.number('1'), audio: audioPlaceholder('one'),
            instructional: 'This is the number 1. It means one thing. Tap the number 1!',
            activity: { kind: 'tap_select', prompt: 'Tap number 1', choices: [
              { label: '1', image: VISUALS.number('1'), correct: true },
              { label: '4', image: VISUALS.number('4'), correct: false },
              { label: '7', image: VISUALS.number('7'), correct: false } ] } },
          { title: 'Number 3 — Match to Quantity', lesson_type: 'number', interactive_type: 'match', skill_name: 'Matches number to quantity',
            image: VISUALS.number('3'), audio: audioPlaceholder('three'),
            instructional: 'This is the number 3. Find the group that has 3 things!',
            activity: { kind: 'tap_select', prompt: 'Which group has 3?', choices: [
              { label: '3 dots', image: VISUALS.count(3,'#43A047'), correct: true },
              { label: '5 dots', image: VISUALS.count(5,'#43A047'), correct: false },
              { label: '2 dots', image: VISUALS.count(2,'#43A047'), correct: false } ] } },
          { title: 'Number 5', lesson_type: 'number', interactive_type: 'tap_select', skill_name: 'Recognizes numbers 1-5',
            image: VISUALS.number('5'), audio: audioPlaceholder('five'),
            instructional: 'This is the number 5. Tap the number 5!',
            activity: { kind: 'tap_select', prompt: 'Tap number 5', choices: [
              { label: '5', image: VISUALS.number('5'), correct: true },
              { label: '2', image: VISUALS.number('2'), correct: false },
              { label: '9', image: VISUALS.number('9'), correct: false } ] } }
        ]
      },
      {
        title: 'Shapes & Patterns',
        lessons: [
          { title: 'The Circle', lesson_type: 'shapes', interactive_type: 'tap_select', skill_name: 'Identifies circle',
            image: VISUALS.circle(), audio: audioPlaceholder('circle'),
            instructional: 'This is a circle. It is round. Tap the circle!',
            activity: { kind: 'tap_select', prompt: 'Tap the circle', choices: [
              { label: 'Circle', image: VISUALS.circle(), correct: true },
              { label: 'Square', image: VISUALS.square(), correct: false },
              { label: 'Triangle', image: VISUALS.triangle(), correct: false } ] } },
          { title: 'The Square', lesson_type: 'shapes', interactive_type: 'tap_select', skill_name: 'Identifies square',
            image: VISUALS.square(), audio: audioPlaceholder('square'),
            instructional: 'This is a square. It has 4 sides. Tap the square!',
            activity: { kind: 'tap_select', prompt: 'Tap the square', choices: [
              { label: 'Square', image: VISUALS.square(), correct: true },
              { label: 'Circle', image: VISUALS.circle(), correct: false },
              { label: 'Star', image: VISUALS.star(), correct: false } ] } },
          { title: 'The Triangle', lesson_type: 'shapes', interactive_type: 'tap_select', skill_name: 'Identifies triangle',
            image: VISUALS.triangle(), audio: audioPlaceholder('triangle'),
            instructional: 'This is a triangle. It has 3 sides. Tap the triangle!',
            activity: { kind: 'tap_select', prompt: 'Tap the triangle', choices: [
              { label: 'Triangle', image: VISUALS.triangle(), correct: true },
              { label: 'Square', image: VISUALS.square(), correct: false },
              { label: 'Circle', image: VISUALS.circle(), correct: false } ] } },
          { title: 'Color Pattern', lesson_type: 'patterns', interactive_type: 'tap_select', skill_name: 'Recognizes simple patterns',
            image: VISUALS.generic('AB pattern'), audio: audioPlaceholder('red, blue, red, blue, what comes next?'),
            instructional: 'Look: red, blue, red, blue... What color comes next?',
            activity: { kind: 'tap_select', prompt: 'What comes next? red, blue, red, blue, ___', choices: [
              { label: 'Red', image: VISUALS.color('#E53935','red'), correct: true },
              { label: 'Green', image: VISUALS.color('#43A047','green'), correct: false },
              { label: 'Yellow', image: VISUALS.color('#FDD835','yellow'), correct: false } ] } }
        ]
      }
    ]
  },
  {
    name: 'Science & Discovery (Kindergarten)',
    subject: 'Science',
    description: 'Animals, weather, plants, and simple observations of the world.',
    units: [
      {
        title: 'Animals',
        lessons: [
          { title: 'Meet the Cat', lesson_type: 'discovery', interactive_type: 'flip_card', skill_name: 'Identifies animals',
            image: VISUALS.cat(), audio: audioPlaceholder('A cat says meow'),
            instructional: 'This is a cat. A cat says "meow". Cats have whiskers and soft fur.',
            activity: { kind: 'flip_card', front: 'Cat', back: 'A cat says "meow"', example: 'Cats have whiskers, fur, and a tail.' } },
          { title: 'Meet the Dog', lesson_type: 'discovery', interactive_type: 'flip_card', skill_name: 'Identifies animals',
            image: VISUALS.dog(), audio: audioPlaceholder('A dog says woof'),
            instructional: 'This is a dog. A dog says "woof". Dogs like to play and run.',
            activity: { kind: 'flip_card', front: 'Dog', back: 'A dog says "woof"', example: 'Dogs have floppy ears and a wagging tail.' } },
          { title: 'Match the Animal Sound', lesson_type: 'discovery', interactive_type: 'match', skill_name: 'Matches animal to sound',
            image: VISUALS.bird(), audio: audioPlaceholder('Which animal says tweet?'),
            instructional: 'Animals make different sounds. Which animal says "tweet"?',
            activity: { kind: 'tap_select', prompt: 'Which animal says "tweet"?', choices: [
              { label: 'Bird', image: VISUALS.bird(), correct: true },
              { label: 'Cat', image: VISUALS.cat(), correct: false },
              { label: 'Fish', image: VISUALS.fish(), correct: false } ] } }
        ]
      },
      {
        title: 'Weather',
        lessons: [
          { title: 'Sunny Day', lesson_type: 'discovery', interactive_type: 'flip_card', skill_name: 'Recognizes weather types',
            image: VISUALS.sun(), audio: audioPlaceholder('The sun is bright and warm'),
            instructional: 'When it is sunny, the sun is out. It is bright and warm!',
            activity: { kind: 'flip_card', front: 'Sunny', back: 'The sun is bright and warm', example: 'We can play outside on a sunny day.' } },
          { title: 'Rainy Day', lesson_type: 'discovery', interactive_type: 'tap_select', skill_name: 'Recognizes weather types',
            image: VISUALS.rain(), audio: audioPlaceholder('Rain falls from clouds'),
            instructional: 'When it rains, water falls from the clouds. Which picture shows rain?',
            activity: { kind: 'tap_select', prompt: 'Which one shows rain?', choices: [
              { label: 'Rain', image: VISUALS.rain(), correct: true },
              { label: 'Sun', image: VISUALS.sun(), correct: false },
              { label: 'Snow', image: VISUALS.snow(), correct: false } ] } }
        ]
      },
      {
        title: 'Plants',
        lessons: [
          { title: 'Parts of a Plant', lesson_type: 'discovery', interactive_type: 'flip_card', skill_name: 'Matches plant parts',
            image: VISUALS.flower(), audio: audioPlaceholder('A plant has roots, a stem, and leaves'),
            instructional: 'A plant has roots, a stem, leaves, and a flower. Plants need sun and water.',
            activity: { kind: 'flip_card', front: 'Plant', back: 'Roots, stem, leaves, flower', example: 'Plants need sunlight and water to grow.' } },
          { title: 'Find the Tree', lesson_type: 'discovery', interactive_type: 'tap_select', skill_name: 'Understands simple observations',
            image: VISUALS.tree(), audio: audioPlaceholder('A tree is a big plant'),
            instructional: 'A tree is a big plant with a trunk and leaves. Which one is a tree?',
            activity: { kind: 'tap_select', prompt: 'Which one is a tree?', choices: [
              { label: 'Tree', image: VISUALS.tree(), correct: true },
              { label: 'Flower', image: VISUALS.flower(), correct: false },
              { label: 'Sun', image: VISUALS.sun(), correct: false } ] } }
        ]
      }
    ]
  },
  {
    name: 'Art & Music (Kindergarten)',
    subject: 'Art',
    description: 'Colors, creativity, rhythm, sound patterns, and simple sing-along activities.',
    units: [
      {
        title: 'Colors',
        lessons: [
          { title: 'Primary Colors', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes primary colors lesson',
            image: VISUALS.color('#E53935','Red'), audio: audioPlaceholder('Let us learn colors. Red, blue, yellow, green, and orange.'),
            instructional: 'Learn five colors one at a time. Listen, look, and tap the matching color.',
            activity: { kind: 'activity_flow', title: 'Primary Colors', steps: [
              { title: 'Red', skill_name: 'Identifies color red', image: VISUALS.color('#E53935','red'), audio: audioPlaceholder('This color is red.'), instruction: 'Tap the color red.', choices: [
                { label: 'Red', image: VISUALS.color('#E53935','red'), correct: true },
                { label: 'Blue', image: VISUALS.color('#1E88E5','blue'), correct: false },
                { label: 'Green', image: VISUALS.color('#43A047','green'), correct: false } ] },
              { title: 'Blue', skill_name: 'Identifies color blue', image: VISUALS.color('#1E88E5','blue'), audio: audioPlaceholder('This color is blue.'), instruction: 'Tap the color blue.', choices: [
                { label: 'Blue', image: VISUALS.color('#1E88E5','blue'), correct: true },
                { label: 'Yellow', image: VISUALS.color('#FDD835','yellow'), correct: false },
                { label: 'Red', image: VISUALS.color('#E53935','red'), correct: false } ] },
              { title: 'Yellow', skill_name: 'Identifies color yellow', image: VISUALS.color('#FDD835','yellow'), audio: audioPlaceholder('This color is yellow.'), instruction: 'Tap the color yellow.', choices: [
                { label: 'Yellow', image: VISUALS.color('#FDD835','yellow'), correct: true },
                { label: 'Blue', image: VISUALS.color('#1E88E5','blue'), correct: false },
                { label: 'Orange', image: VISUALS.color('#FB8C00','orange'), correct: false } ] },
              { title: 'Green', skill_name: 'Identifies color green', image: VISUALS.color('#43A047','green'), audio: audioPlaceholder('This color is green.'), instruction: 'Tap the color green.', choices: [
                { label: 'Green', image: VISUALS.color('#43A047','green'), correct: true },
                { label: 'Red', image: VISUALS.color('#E53935','red'), correct: false },
                { label: 'Yellow', image: VISUALS.color('#FDD835','yellow'), correct: false } ] },
              { title: 'Orange', skill_name: 'Identifies color orange', image: VISUALS.color('#FB8C00','orange'), audio: audioPlaceholder('This color is orange.'), instruction: 'Tap the color orange.', choices: [
                { label: 'Orange', image: VISUALS.color('#FB8C00','orange'), correct: true },
                { label: 'Blue', image: VISUALS.color('#1E88E5','blue'), correct: false },
                { label: 'Green', image: VISUALS.color('#43A047','green'), correct: false } ] }
            ] } }
        ]
      },
      {
        title: 'Music & Sound',
        lessons: [
          { title: 'Clap to the Beat', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes clap to the beat lesson',
            image: VISUALS.music(), audio: audioPlaceholder('Clap to the beat. Slow, slow, slow. Fast, fast, fast.'),
            instructional: 'Music has a beat. Listen, clap, and repeat the rhythm.',
            activity: { kind: 'activity_flow', title: 'Clap to the Beat', steps: [
              { title: 'Listen to a Slow Beat', skill_name: 'Listens to a slow beat', image: VISUALS.music(), audio: audioPlaceholder('clap ... clap ... clap'), instruction: 'Listen to the slow beat.' },
              { title: 'Clap the Slow Beat', skill_name: 'Claps a slow beat', image: VISUALS.music(), audio: audioPlaceholder('clap ... clap ... clap'), instruction: 'Clap your hands slowly three times.' },
              { title: 'Listen to a Fast Beat', skill_name: 'Listens to a fast beat', image: VISUALS.music(), audio: audioPlaceholder('clap clap clap clap'), instruction: 'Listen to the fast beat.' },
              { title: 'Clap the Fast Beat', skill_name: 'Claps a fast beat', image: VISUALS.music(), audio: audioPlaceholder('clap clap clap clap'), instruction: 'Clap your hands quickly four times.' },
              { title: 'Repeat the Pattern', skill_name: 'Repeats a rhythm pattern', image: VISUALS.music(), audio: audioPlaceholder('slow, slow, fast fast'), instruction: 'Try the pattern: slow, slow, fast-fast.' }
            ] } },
          { title: 'Sing-Along: Clap Your Hands', lesson_type: 'song', interactive_type: 'sing_along', skill_name: 'Completes sing-along activity',
            image: VISUALS.music(), audio: audioPlaceholder('Clap your hands, clap your hands, clap them with me.'),
            instructional: 'Listen to the song, sing the words, and clap along.',
            activity: { kind: 'sing_along', title: 'Clap Your Hands', steps: [
              { title: 'Listen to the Song', skill_name: 'Listens to a simple song', image: VISUALS.music(), audio: audioPlaceholder('Clap your hands, clap your hands, clap them with me.'), lyrics: ['Clap your hands, clap your hands,', 'Clap them with me.'] },
              { title: 'Sing the First Line', skill_name: 'Repeats simple song words', image: VISUALS.music(), audio: audioPlaceholder('Clap your hands, clap your hands'), instruction: 'Sing: Clap your hands, clap your hands.' },
              { title: 'Clap the Beat', skill_name: 'Claps with a song beat', image: VISUALS.music(), audio: audioPlaceholder('clap clap clap'), instruction: 'Clap with the words.' },
              { title: 'Sing and Move', skill_name: 'Combines singing and movement', image: VISUALS.music(), audio: audioPlaceholder('Clap them with me.'), instruction: 'Sing the last line and clap along.' },
              { title: 'Finish the Song', skill_name: 'Completes song participation', image: VISUALS.music(), audio: audioPlaceholder('Great singing.'), instruction: 'Finish the song with a big smile!' }
            ] } }
        ]
      },
      {
        title: 'Creative Art',
        lessons: [
          { title: 'Make a Picture', lesson_type: 'activity', interactive_type: 'flip_card', skill_name: 'Completes simple creative art activity',
            image: VISUALS.paint(), audio: audioPlaceholder('Let us paint a picture'),
            instructional: 'Let\'s be creative! Use your favorite colors to make a picture with a grown-up.',
            activity: { kind: 'flip_card', front: '🎨 Create', back: 'Draw or paint anything you like!', example: 'Use red, blue, and green. Have fun!' } }
        ]
      }
    ]
  },
  {
    name: 'Movement & Play (Kindergarten)',
    subject: 'PE',
    description: 'Simple movement, body awareness, balance, rhythm, coordination, and active play.',
    units: [
      {
        title: 'Body Movement',
        lessons: [
          { title: 'Stretch Up High', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes stretch activity',
            image: VISUALS.stretchKid(), audio: audioPlaceholder('Reach up high and stretch.'),
            instructional: 'Stretch your arms up high like you are reaching for the sky.',
            activity: { kind: 'activity_flow', title: 'Stretch Up High', steps: [
              { title: 'Stand Tall', skill_name: 'Stands tall for movement', image: VISUALS.stretchKid(), audio: audioPlaceholder('Stand tall.'), instruction: 'Stand tall with your feet on the floor.' },
              { title: 'Reach Up', skill_name: 'Reaches arms overhead', image: VISUALS.stretchKid(), audio: audioPlaceholder('Reach up high.'), instruction: 'Reach both arms up high like you are touching the sky.' },
              { title: 'Hold the Stretch', skill_name: 'Holds a simple stretch', image: VISUALS.stretchKid(), audio: audioPlaceholder('Hold it. One, two, three.'), instruction: 'Hold the stretch while you count to three.' }
            ] } },
          { title: 'Touch Your Toes', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes toe touch activity',
            image: VISUALS.toeTouch(), audio: audioPlaceholder('Bend down and touch your toes.'),
            instructional: 'Practice bending and stretching safely with a grown-up nearby.',
            activity: { kind: 'activity_flow', title: 'Touch Your Toes', steps: [
              { title: 'Stand Tall', skill_name: 'Prepares for toe touch', image: VISUALS.stretchKid(), audio: audioPlaceholder('Stand tall.'), instruction: 'Stand tall with your feet apart.' },
              { title: 'Bend Down', skill_name: 'Bends safely', image: VISUALS.toeTouch(), audio: audioPlaceholder('Bend down slowly.'), instruction: 'Bend down slowly and keep your knees soft.' },
              { title: 'Reach for Toes', skill_name: 'Attempts toe touch', image: VISUALS.toeTouch(), audio: audioPlaceholder('Reach for your toes.'), instruction: 'Reach toward your toes.' }
            ] } },
          { title: 'Jump Like a Frog', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes frog jump activity',
            image: VISUALS.frogJump(), audio: audioPlaceholder('Jump up high like a frog'),
            instructional: 'Crouch down low, then jump up high like a frog. Make sure you have safe space.',
            activity: { kind: 'activity_flow', title: 'Jump Like a Frog', steps: [
              { title: 'Crouch Low', skill_name: 'Crouches safely', image: VISUALS.frogJump(), audio: audioPlaceholder('Crouch down low.'), instruction: 'Crouch down low like a frog.' },
              { title: 'Jump Up', skill_name: 'Jumps with control', image: VISUALS.frogJump(), audio: audioPlaceholder('Jump up high.'), instruction: 'Jump up high one time and land softly.' },
              { title: 'Do Five Frog Jumps', skill_name: 'Repeats simple movement', image: VISUALS.frogJump(), audio: audioPlaceholder('Do five frog jumps.'), instruction: 'Try five frog jumps with a grown-up.' }
            ] } },
          { title: 'March in Place', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes march in place activity',
            image: VISUALS.marchKid(), audio: audioPlaceholder('March in place. Left, right, left, right.'),
            instructional: 'March your feet like you are walking in one spot.',
            activity: { kind: 'activity_flow', title: 'March in Place', steps: [
              { title: 'Start Marching', skill_name: 'Starts marching in place', image: VISUALS.marchKid(), audio: audioPlaceholder('March in place.'), instruction: 'Lift one knee, then the other.' },
              { title: 'Count to Ten', skill_name: 'Counts while moving', image: VISUALS.marchKid(), audio: audioPlaceholder('Count to ten while marching.'), instruction: 'March and count to ten.' },
              { title: 'Stop Safely', skill_name: 'Stops on direction', image: VISUALS.freezeDance(), audio: audioPlaceholder('Stop.'), instruction: 'Freeze when you hear stop.' }
            ] } }
        ]
      },
      {
        title: 'Balance & Coordination',
        lessons: [
          { title: 'Balance on One Foot', lesson_type: 'activity', interactive_type: 'flip_card', skill_name: 'Practices balance on one foot',
            image: VISUALS.balanceKid(), audio: audioPlaceholder('Balance on one foot.'),
            instructional: 'Hold onto a chair or grown-up if needed. Try balancing on one foot.',
            activity: { kind: 'flip_card', front: 'Balance on one foot', back: 'Lift one foot, hold still, and count to three.', example: 'Then switch and try the other foot too!' } },
          { title: 'Toss the Ball', lesson_type: 'activity', interactive_type: 'flip_card', skill_name: 'Practices hand-eye coordination',
            image: VISUALS.tossBall(), audio: audioPlaceholder('Toss the ball and catch it'),
            instructional: 'Find a soft ball. Toss it up gently and try to catch it. Great hand-eye practice!',
            activity: { kind: 'flip_card', front: 'Toss and catch', back: 'Toss the ball up gently, watch it, then catch it with your hands.', example: 'Count how many times you can catch it.' } },
          { title: 'Hop Like a Bunny', lesson_type: 'activity', interactive_type: 'flip_card', skill_name: 'Practices hopping movement',
            image: VISUALS.bunnyHop(), audio: audioPlaceholder('Hop like a bunny.'),
            instructional: 'Hop forward safely like a bunny.',
            activity: { kind: 'flip_card', front: 'Hop like a bunny', back: 'Bend your knees, hop forward, and land softly on your feet.', example: 'Try five bunny hops.' } }
        ]
      },
      {
        title: 'Rhythm & Active Play',
        lessons: [
          { title: 'Clap and Step', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes clap and step pattern',
            image: VISUALS.clapStep(), audio: audioPlaceholder('Clap, step, clap, step.'),
            instructional: 'Practice a simple movement pattern.',
            activity: { kind: 'activity_flow', title: 'Clap and Step', steps: [
              { title: 'Clap', skill_name: 'Claps on cue', image: VISUALS.clapStep(), audio: audioPlaceholder('Clap.'), instruction: 'Clap your hands one time.' },
              { title: 'Step', skill_name: 'Steps on cue', image: VISUALS.clapStep(), audio: audioPlaceholder('Step.'), instruction: 'Take one step in place.' },
              { title: 'Pattern', skill_name: 'Follows clap and step pattern', image: VISUALS.clapStep(), audio: audioPlaceholder('Clap, step, clap, step.'), instruction: 'Try: clap, step, clap, step.' }
            ] } },
          { title: 'Animal Walks', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Completes animal walks activity',
            image: VISUALS.cat(), audio: audioPlaceholder('Move like an animal.'),
            instructional: 'Pretend to move like different animals.',
            activity: { kind: 'activity_flow', title: 'Animal Walks', steps: [
              { title: 'Cat Walk', skill_name: 'Moves like a cat', image: VISUALS.cat(), audio: audioPlaceholder('Walk softly like a cat.'), instruction: 'Walk softly like a cat.' },
              { title: 'Dog Walk', skill_name: 'Moves like a dog', image: VISUALS.dog(), audio: audioPlaceholder('Walk like a dog.'), instruction: 'Pretend to walk like a dog.' },
              { title: 'Bird Flap', skill_name: 'Moves like a bird', image: VISUALS.bird(), audio: audioPlaceholder('Flap your wings like a bird.'), instruction: 'Flap your arms like bird wings.' }
            ] } },
          { title: 'Freeze Dance', lesson_type: 'activity', interactive_type: 'flip_card', skill_name: 'Stops movement on cue',
            image: VISUALS.freezeDance(), audio: audioPlaceholder('Dance, dance, freeze.'),
            instructional: 'Dance when the music plays and freeze when it stops.',
            activity: { kind: 'flip_card', front: 'Freeze dance', back: 'Dance while the music is playing, then freeze your body when it stops.', example: 'Ask a grown-up to say freeze.' } },
          { title: 'Move Fast and Slow', lesson_type: 'activity', interactive_type: 'activity_flow', skill_name: 'Understands fast and slow movement',
            image: VISUALS.fastSlow(), audio: audioPlaceholder('Move fast. Move slow.'),
            instructional: 'Practice moving fast and slow safely.',
            activity: { kind: 'activity_flow', title: 'Move Fast and Slow', steps: [
              { title: 'Slow Walk', skill_name: 'Moves slowly on cue', image: VISUALS.fastSlow(), audio: audioPlaceholder('Move slowly.'), instruction: 'Walk slowly in place.' },
              { title: 'Fast March', skill_name: 'Moves quickly on cue', image: VISUALS.fastSlow(), audio: audioPlaceholder('Move fast.'), instruction: 'March quickly in place.' },
              { title: 'Switch Speeds', skill_name: 'Changes movement speed on cue', image: VISUALS.fastSlow(), audio: audioPlaceholder('Slow, fast, slow.'), instruction: 'Switch between slow and fast.' }
            ] } }
        ]
      }
    ]
  }

];

// ----------------------------------------------------------------
// MAIN
// ----------------------------------------------------------------
async function main() {
  console.log('============================================');
  console.log('JNM Home Education Program');
  console.log('Kindergarten Seed (grade_level = 0)');
  console.log('============================================\n');

  const stats = { courses: 0, units: 0, lessons: 0, skills: new Set() };

  try {
    // Safety: ensure media columns exist (migration should already have added them)
    await pool.query('ALTER TABLE lessons ADD COLUMN IF NOT EXISTS image_url TEXT');
    await pool.query('ALTER TABLE lessons ADD COLUMN IF NOT EXISTS audio_url TEXT');
    await pool.query('ALTER TABLE lessons ADD COLUMN IF NOT EXISTS lesson_type TEXT');
    await pool.query('ALTER TABLE lessons ADD COLUMN IF NOT EXISTS interactive_type TEXT');
    await pool.query('ALTER TABLE lessons ADD COLUMN IF NOT EXISTS activity_data JSONB');
    await pool.query('ALTER TABLE lessons ADD COLUMN IF NOT EXISTS skill_name TEXT');

    for (const course of K) {
      // Create or find the course (grade_level = 0)
      let cRes = await pool.query(
        "SELECT id FROM courses WHERE name = $1 AND grade_level = 0",
        [course.name]
      );
      let courseId;
      if (cRes.rows.length === 0) {
        const ins = await pool.query(
          "INSERT INTO courses (name, grade_level, subject, course_type, description, credit_hours, is_active) VALUES ($1, 0, $2, 'core', $3, 0, true) RETURNING id",
          [course.name, course.subject, course.description]
        );
        courseId = ins.rows[0].id;
        stats.courses++;
        console.log('Created course:', course.name);
      } else {
        courseId = cRes.rows[0].id;
        console.log('Found course:', course.name);
      }

      let unitNum = 0;
      for (const unit of course.units) {
        unitNum++;
        let uRes = await pool.query('SELECT id FROM units WHERE course_id = $1 AND unit_number = $2', [courseId, unitNum]);
        let unitId;
        if (uRes.rows.length === 0) {
          const ins = await pool.query(
            'INSERT INTO units (course_id, title, description, unit_number, is_active) VALUES ($1,$2,$3,$4,true) RETURNING id',
            [courseId, unit.title, unit.title, unitNum]
          );
          unitId = ins.rows[0].id;
          stats.units++;
        } else {
          unitId = uRes.rows[0].id;
        }

        let lessonNum = 0;
        for (const lesson of unit.lessons) {
          lessonNum++;
          stats.skills.add(lesson.skill_name);
          const activityJson = JSON.stringify(lesson.activity || {});
          let lRes = await pool.query('SELECT id FROM lessons WHERE unit_id = $1 AND lesson_number = $2', [unitId, lessonNum]);
          if (lRes.rows.length === 0) {
            await pool.query(
              `INSERT INTO lessons (unit_id, title, description, lesson_number, content, instructional_content,
                 image_url, audio_url, lesson_type, interactive_type, activity_data, skill_name, is_active)
               VALUES ($1,$2,$3,$4,$5,$5,$6,$7,$8,$9,$10,$11,true)`,
              [unitId, lesson.title, lesson.title, lessonNum, lesson.instructional,
               lesson.image, lesson.audio, lesson.lesson_type, lesson.interactive_type, activityJson, lesson.skill_name]
            );
            stats.lessons++;
          } else {
            await pool.query(
              `UPDATE lessons SET title=$1, instructional_content=$2, content=$2, image_url=$3, audio_url=$4,
                 lesson_type=$5, interactive_type=$6, activity_data=$7, skill_name=$8, is_active=true WHERE id=$9`,
              [lesson.title, lesson.instructional, lesson.image, lesson.audio,
               lesson.lesson_type, lesson.interactive_type, activityJson, lesson.skill_name, lRes.rows[0].id]
            );
          }
        }
        // If the curriculum was reorganized, hide old extra lessons from previous seed runs.
        await pool.query('UPDATE lessons SET is_active=false WHERE unit_id=$1 AND lesson_number > $2', [unitId, lessonNum]);
      }
      // If the curriculum was reorganized, hide old extra units from previous seed runs.
      await pool.query('UPDATE units SET is_active=false WHERE course_id=$1 AND unit_number > $2', [courseId, unitNum]);
      console.log('  ', course.units.length, 'units,',
        course.units.reduce((s,u)=>s+u.lessons.length,0), 'lessons');
    }

    console.log('\n============================================');
    console.log('KINDERGARTEN SEED COMPLETE');
    console.log('============================================');
    console.log('Courses:', stats.courses, '| Units:', stats.units, '| Lessons:', stats.lessons);
    console.log('Unique skills tracked:', stats.skills.size);
    console.log('\nKindergarten courses are grade_level = 0 and display as "Kindergarten".');
    console.log('Assessment is skill-based (Introduced / Practicing / Recognized / Needs More Practice / Mastered).');
    console.log('Visuals are topic-matched inline SVG; audio uses clearly-marked tts-placeholder values.');
    console.log('============================================');
  } catch (err) {
    console.error('Fatal error:', err);
  } finally {
    await pool.end();
  }
}

main();
