#!/usr/bin/env python3
"""
Week 22: 3D Shapes
Phase 4: Geometry & Fractions

Standards: 2.G.A.1 (identify 3D shapes; faces, edges, vertices;
nets; real-world examples; compare 2D and 3D)

New Standard:
- Reduced drill (40% fewer problems)
- Estimation before counting ("Estimate First!" — guess faces/edges before counting)
- Multiple strategies (two ways to count/describe solids)
- Better word problems (reasoning, real-world scenarios)
- Open-ended challenges (Create Your Own solids/riddles)
- Number talks (reason about solids WITHOUT counting)
- Friday self-check with emoji reflection
- Fact fluency warmup daily
- Word problems every day
"""

import os
import glob
from weasyprint import HTML

from math_helpers import (
    CSS, TEACHER_CSS,
    page, page_multi, hdr, sec, b, bw, bl,
    tg_page_multi, tg_sec, tg_note, tg_section_title,
    shape_svg,
)
from activity_builders import (
    build_challenge_box,
)

BASE = os.path.expanduser("~/Home_School/2nd_Grade/Math")
WEEK = os.path.join(BASE, "Week_22")

BLUE = "#4a90d9"
GREEN = "#5cb85c"
RED = "#d9534f"
ORANGE = "#f0ad4e"
PURPLE = "#9b59b6"


# ── Custom 3D shape SVGs (no 3D builders exist in activity_builders.py) ──

def cube_svg(color=BLUE, size=54):
    return (f'<svg viewBox="0 0 54 54" width="{size}" height="{size}">'
            f'<polygon points="8,16 34,16 34,42 8,42" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.55"/>'
            f'<polygon points="8,16 20,6 46,6 34,16" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.75"/>'
            f'<polygon points="34,16 46,6 46,32 34,42" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.4"/>'
            f'</svg>')


def rect_prism_svg(color=GREEN, size=58):
    return (f'<svg viewBox="0 0 66 48" width="{size+8}" height="{size-10}">'
            f'<polygon points="4,16 44,16 44,42 4,42" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.55"/>'
            f'<polygon points="4,16 16,6 56,6 44,16" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.75"/>'
            f'<polygon points="44,16 56,6 56,32 44,42" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.4"/>'
            f'</svg>')


def sphere_svg(color=RED, size=50):
    return (f'<svg viewBox="0 0 50 50" width="{size}" height="{size}">'
            f'<circle cx="25" cy="25" r="20" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.55"/>'
            f'<ellipse cx="25" cy="25" rx="20" ry="7" fill="none" stroke="#333" stroke-width="1" stroke-dasharray="3,2" opacity="0.6"/>'
            f'</svg>')


def cone_svg(color=ORANGE, size=50):
    return (f'<svg viewBox="0 0 50 54" width="{size}" height="{size}">'
            f'<polygon points="25,4 45,42 5,42" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.55"/>'
            f'<ellipse cx="25" cy="42" rx="20" ry="7" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.7"/>'
            f'</svg>')


def cylinder_svg(color=PURPLE, size=50):
    return (f'<svg viewBox="0 0 44 54" width="{size-6}" height="{size}">'
            f'<rect x="4" y="10" width="36" height="34" fill="{color}" stroke="none" opacity="0.55"/>'
            f'<ellipse cx="22" cy="44" rx="18" ry="7" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.7"/>'
            f'<line x1="4" y1="10" x2="4" y2="44" stroke="#333" stroke-width="1.5"/>'
            f'<line x1="40" y1="10" x2="40" y2="44" stroke="#333" stroke-width="1.5"/>'
            f'<ellipse cx="22" cy="10" rx="18" ry="7" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.85"/>'
            f'</svg>')


def pyramid_svg(color=RED, size=52):
    return (f'<svg viewBox="0 0 54 50" width="{size}" height="{size-4}">'
            f'<polygon points="27,4 50,42 12,42" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.6"/>'
            f'<polygon points="27,4 12,42 4,34" fill="{color}" stroke="#333" stroke-width="1.5" opacity="0.4"/>'
            f'</svg>')


def cube_net_svg(color=BLUE, size=70):
    """Cross-shaped net of a cube."""
    c, s = color, 16
    cells = [(1, 0), (0, 1), (1, 1), (2, 1), (1, 2), (1, 3)]
    rects = ''.join(
        f'<rect x="{x*s+2}" y="{y*s+2}" width="{s}" height="{s}" fill="{c}" '
        f'stroke="#333" stroke-width="1" opacity="0.5"/>' for x, y in cells)
    return f'<svg viewBox="0 0 52 68" width="{size-14}" height="{size}">{rects}</svg>'


def cylinder_net_svg(color=PURPLE, size=70):
    """Net of a cylinder: rectangle + two circles."""
    return (f'<svg viewBox="0 0 60 66" width="{size-10}" height="{size}">'
            f'<circle cx="30" cy="10" r="8" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'<rect x="8" y="20" width="44" height="26" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'<circle cx="30" cy="56" r="8" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'</svg>')


def pyramid_net_svg(color=RED, size=70):
    """Net of a square pyramid: square + 4 triangles."""
    return (f'<svg viewBox="0 0 64 64" width="{size}" height="{size}">'
            f'<rect x="22" y="22" width="20" height="20" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'<polygon points="22,22 42,22 32,4" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'<polygon points="22,42 42,42 32,60" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'<polygon points="22,22 22,42 4,32" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'<polygon points="42,22 42,42 60,32" fill="{color}" stroke="#333" stroke-width="1" opacity="0.5"/>'
            f'</svg>')


SOLIDS = {
    "cube": cube_svg,
    "rectangular prism": rect_prism_svg,
    "sphere": sphere_svg,
    "cone": cone_svg,
    "cylinder": cylinder_svg,
    "pyramid": pyramid_svg,
}


# ═══════════════════════════════════════════════════
# MONDAY — Meet the 3D Shapes
# ═══════════════════════════════════════════════════
def monday():
    # 1: Fluency warmup — 2D review (bridge from Week 21)
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Quick 2D review from last week!</p>'\
         '<div class="mgrid c2">'
    s1 += f'<div class="abox"><p>Sides on a square: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Vertices on a triangle: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Sides on a hexagon: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>A 5-sided polygon is a: {b("7em")}</p></div>'
    s1 += '</div></div>'

    # 2: New concept — 2D is flat, 3D is solid; meet the solids
    s2 = '<p class="note"><b>2D shapes are flat</b> — they live on paper. '\
         '<b>3D shapes are solid</b> — you can hold them! Meet the six solids:</p>'\
         '<div class="mgrid c3">'
    for name in ["cube", "rectangular prism", "sphere", "cone", "cylinder", "pyramid"]:
        s2 += f'<div class="abox" style="text-align:center;">{SOLIDS[name](size=48)}'\
              f'<p><b>{name.title()}</b></p></div>'
    s2 += '</div>'

    # 3: Name the solid (reduced from 8 to 5)
    s3 = '<p class="note">Write the name of each solid. Use the word bank: '\
         'cube, sphere, cone, cylinder, pyramid.</p>'\
         '<div class="mgrid c3">'
    for name in ["cone", "cube", "sphere", "pyramid", "cylinder"]:
        s3 += f'<div class="abox" style="text-align:center;">{SOLIDS[name](size=46)}'\
              f'<p>{b("7em")}</p></div>'
    s3 += '</div>'

    # 4: NEW — Number Talk
    s4 = '<div class="abox" style="background:#e3f2fd;">'\
         '<p><b>Number Talk</b> — Explain WITHOUT touching or counting.</p>'\
         '<div class="mgrid c2">'
    s4 += '<div class="abox"><p>A sphere can roll but a cube cannot. What about their shapes '\
          'makes this true?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s4 += '<div class="abox"><p>Is a circle the same as a sphere? Explain the difference '\
          'between flat and solid.</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s4 += '</div></div>'

    # 5: Word problem
    s5 = '<div class="wp">'\
         '<p class="note">Read carefully. Think about what is happening.</p>'\
         '<div class="abox"><p>Theo is packing a box with blocks. He has 4 cubes, 3 cylinders, '\
         'and 2 cones. How many solids that can ROLL does he have? '\
         '(Hint: which of these solids have a curved surface?)</p>'\
         '<p style="font-size:11px;">My thinking: ' + bw() + '</p>'\
         '<p>' + b("3em") + ' rolling solids</p></div></div>'

    return page(22, "Monday", "Meet the 3D Shapes",
        f'''{sec(1, "Warm-up: 2D Review", s1)}
{sec(2, "Flat vs. Solid: The Six Solids", s2)}
{sec(3, "Name That Solid", s3)}
{sec(4, "Number Talk: Roll or Not?", s4)}
{sec(5, "Word Problem", s5)}''')


# ═══════════════════════════════════════════════════
# TUESDAY — Faces, Edges & Vertices
# ═══════════════════════════════════════════════════
def tuesday():
    # 1: Fluency warmup
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Name that solid, fast!</p>'\
         '<div class="mgrid c2">'
    clues = [
        "I look like a ball:",
        "I look like a dice:",
        "I look like a can:",
        "I look like a party hat:",
    ]
    for c in clues:
        s1 += f'<div class="abox"><p>{c} {b("6em")}</p></div>'
    s1 += '</div></div>'

    # 2: New words — faces, edges, vertices with guided example
    s2 = '<p class="note">Solids have three things we can count:<br>'\
         '• <b>Faces</b> — the flat sides<br>'\
         '• <b>Edges</b> — where two faces meet<br>'\
         '• <b>Vertices</b> — the pointy corners</p>'
    s2 += f'<div class="abox"><p style="text-align:center;">{cube_svg(BLUE, 64)}</p>'\
          '<p style="text-align:center;">A cube has <b>6 faces</b>, <b>12 edges</b>, and '\
          '<b>8 vertices</b>. Grab a dice or a block and touch each one as you count!</p></div>'

    # 3: NEW — Estimate First!
    s3 = '<div class="abox" style="background:#fff3e0;">'\
         '<p><b>Estimate First!</b> Before counting, GUESS how many faces each solid has. '\
         'Then count with a real object if you can.</p>'\
         '<div class="mgrid c2">'
    for name in ["rectangular prism", "pyramid"]:
        s3 += f'<div class="abox" style="text-align:center;">{SOLIDS[name](size=50)}'\
              f'<p><b>{name.title()}</b></p>'\
              f'<p>My guess: {b("3em")} Actual: {b("3em")}</p></div>'
    s3 += '</div></div>'

    # 4: Count faces, edges, vertices (reduced from 6 to 4)
    s4 = '<p class="note">Fill in the table. Touch and count slowly — edges are the trickiest!</p>'
    s4 += '<table class="tbl"><tr><th>Solid</th><th>Picture</th><th>Faces</th><th>Edges</th><th>Vertices</th></tr>'
    rows = [
        ("Cube", "cube"),
        ("Rectangular Prism", "rectangular prism"),
        ("Pyramid", "pyramid"),
        ("Sphere", "sphere"),
    ]
    for label, key in rows:
        s4 += f'<tr><td>{label}</td><td style="text-align:center;">{SOLIDS[key](size=36)}</td>'\
              f'<td>{b("3em")}</td><td>{b("3em")}</td><td>{b("3em")}</td></tr>'
    s4 += '</table>'

    # 5: Word problem
    s5 = '<div class="wp">'\
         '<p class="note">Read carefully. Draw if it helps!</p>'\
         '<div class="abox"><p>Zara paints one sticker on every face of a cube. '\
         'Stickers come in packs of 4. How many packs does she need to cover all the faces? '\
         'Will she have any stickers left over?</p>'\
         '<p style="font-size:11px;">My thinking: ' + bw() + '</p>'\
         '<p>Packs: ' + b("3em") + ' Left over: ' + b("3em") + '</p></div></div>'

    return page(22, "Tuesday", "Faces, Edges & Vertices",
        f'''{sec(1, "Warm-up: Solid Riddles", s1)}
{sec(2, "New Words: Faces, Edges, Vertices", s2)}
{sec(3, "Estimate First: How Many Faces?", s3)}
{sec(4, "Count Faces, Edges & Vertices", s4)}
{sec(5, "Word Problem", s5)}''')


# ═══════════════════════════════════════════════════
# WEDNESDAY — Nets & Building Solids
# ═══════════════════════════════════════════════════
def wednesday():
    # 1: Fluency warmup
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Faces in a flash!</p>'\
         '<div class="mgrid c2">'
    s1 += f'<div class="abox"><p>Faces on a cube: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Vertices on a cube: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Faces on a sphere: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Vertices on a cone: {b("3em")}</p></div>'
    s1 += '</div></div>'

    # 2: What is a net? Match nets to solids (reduced from 5 to 3)
    s2 = '<p class="note">A <b>net</b> is a solid unfolded flat — like unwrapping a box! '\
         'Draw a line from each net to the solid it folds into.</p>'\
         '<div class="mgrid c2">'
    s2 += f'<div class="abox" style="text-align:center;"><p><b>Nets</b></p>'\
          f'{cube_net_svg()} &nbsp;&nbsp; {cylinder_net_svg()} &nbsp;&nbsp; {pyramid_net_svg()}</div>'
    s2 += f'<div class="abox" style="text-align:center;"><p><b>Solids</b></p>'\
          f'{pyramid_svg(size=44)} &nbsp;&nbsp; {cube_svg(size=44)} &nbsp;&nbsp; {cylinder_svg(size=44)}</div>'
    s2 += '</div>'

    # 3: Reason about nets — which faces? (two strategies)
    s3 = '<div class="abox" style="background:#f3e5f5;">'\
         '<p><b>Show Two Different Ways</b> — How can you tell the cross-shaped net folds into '\
         'a cube and NOT a pyramid?</p>'\
         '<p style="font-size:11px; color:#666;">Ideas: count the faces in the net; look at the SHAPE of each face.</p>'\
         '<p>Way 1: ' + bl() + '</p>'\
         '<p>Way 2: ' + bl() + '</p></div>'

    # 4: Word problems (reduced from 3 to 2)
    s4 = '<div class="wp">'\
         '<p class="note">Read carefully. Think about what is happening.</p>'\
         '<div class="mgrid c2">'
    s4 += '<div class="abox"><p>A cereal box is a rectangular prism. Kim unfolds it flat to '\
          'recycle it. How many rectangle faces will she see in the flattened box?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p>'\
          '<p>' + b("3em") + ' faces</p></div>'
    s4 += '<div class="abox"><p>A pyramid net has 1 square and 4 triangles. If Ben cuts out '\
          '3 pyramid nets, how many triangles does he cut in all?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p>'\
          '<p>' + b("3em") + ' triangles</p></div>'
    s4 += '</div></div>'

    # 5: Challenge — Create your own
    s5 = '<div class="abox" style="background:#f3e5f5;">'\
         '<p><b>Create Your Own Net</b></p>'\
         '<p>Try to draw a net for a cube that is DIFFERENT from the cross shape above. '\
         '(There are 11 different cube nets!) Remember: exactly 6 squares.</p>'\
         '<p style="min-height:100px; border:1px dashed #999; border-radius:4px;"></p>'\
         '<p style="font-size:11px;">Bonus: cut it out and try folding it. Did it work? ' + bw() + '</p></div>'

    return page(22, "Wednesday", "Nets: Unfolding Solids",
        f'''{sec(1, "Warm-up: Face Facts", s1)}
{sec(2, "Match Nets to Solids", s2)}
{sec(3, "Show Two Different Ways", s3)}
{sec(4, "Word Problems", s4)}
{sec(5, "Challenge: Create Your Own Net", s5)}''')


# ═══════════════════════════════════════════════════
# THURSDAY — 3D Shapes in the Real World
# ═══════════════════════════════════════════════════
def thursday():
    # 1: Fluency warmup
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Solid math in your head.</p>'\
         '<div class="mgrid c2">'
    s1 += f'<div class="abox"><p>Faces on 2 cubes: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Vertices on 2 pyramids: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Faces on a cube + a pyramid: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Edges on a cube − edges on a pyramid: {b("3em")}</p></div>'
    s1 += '</div></div>'

    # 2: Real-world matching (reduced from 8 to 5)
    s2 = '<p class="note">Solids are everywhere! Write which solid each object looks like.</p>'\
         '<div class="mgrid c2">'
    objects = [
        "A basketball", "A soup can", "An ice cream cone",
        "A tissue box", "The Great Pyramid in Egypt",
    ]
    for obj in objects:
        s2 += f'<div class="abox"><p>{obj} = {b("8em")}</p></div>'
    s2 += '</div>'

    # 3: Compare 2D and 3D
    s3 = '<p class="note">2D and 3D shapes are related! The faces of solids are 2D shapes.</p>'\
         '<div class="mgrid c2">'
    pairs = [
        ("What 2D shape are the faces of a cube?", "square"),
        ("What 2D shape is the flat face of a cone?", "circle"),
        ("What 2D shapes make a pyramid's faces?", "square + triangles"),
        ("What 2D shape do you see at the ends of a cylinder?", "circle"),
    ]
    for q, _ in pairs:
        s3 += f'<div class="abox"><p>{q}</p><p>{b("7em")}</p></div>'
    s3 += '</div>'

    # 4: NEW — Number Talk
    s4 = '<div class="abox" style="background:#e3f2fd;">'\
         '<p><b>Number Talk</b> — Explain WITHOUT counting.</p>'\
         '<div class="mgrid c2">'
    s4 += '<div class="abox"><p>A cube and a rectangular prism have the same number of faces, '\
          'edges, and vertices. Why do you think that is?</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s4 += '<div class="abox"><p>Which would stack better in a cupboard: cans (cylinders) or '\
          'balls (spheres)? Explain using faces and curves.</p>'\
          '<p style="font-size:11px;">My thinking: ' + bw() + '</p></div>'
    s4 += '</div></div>'

    # 5: Word problem + create your own
    s5 = '<div class="wp">'\
         '<p class="note">Read carefully. Then create your own!</p>'\
         '<div class="abox"><p>A grocery store stacks 5 soup cans in a row. Each can has 2 circle '\
         'faces (top and bottom). How many circle faces are in the whole row?</p>'\
         '<p style="font-size:11px;">My thinking: ' + bw() + '</p>'\
         '<p>' + b("3em") + ' circle faces</p></div>'\
         '<div class="abox" style="background:#f3e5f5; margin-top:8px;">'\
         '<p><b>Create Your Own</b> — Go on a 3D shape hunt in your house! '\
         'Find one real object for each solid and write it down.</p>'\
         '<p>Cube: ' + bw() + ' Sphere: ' + bw() + '</p>'\
         '<p>Cylinder: ' + bw() + ' Cone or Pyramid: ' + bw() + '</p></div></div>'

    return page(22, "Thursday", "3D Shapes in the Real World",
        f'''{sec(1, "Warm-up: Solid Math", s1)}
{sec(2, "Real-World Solids", s2)}
{sec(3, "Compare 2D and 3D", s3)}
{sec(4, "Number Talk: Reason About Solids", s4)}
{sec(5, "Word Problem & Shape Hunt", s5)}''')


# ═══════════════════════════════════════════════════
# FRIDAY — Review & Self-Check
# ═══════════════════════════════════════════════════
def friday():
    # 1: Fluency warmup
    s1 = '<div class="abox" style="background:#e8f5e9;">'\
         '<p><b>2-min Fluency Warm-up</b> — Go fast!</p>'\
         '<div class="mgrid c2">'
    s1 += f'<div class="abox"><p>Faces on a cube: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>A ball is shaped like a: {b("6em")}</p></div>'
    s1 += f'<div class="abox"><p>Edges on a cube: {b("3em")}</p></div>'
    s1 += f'<div class="abox"><p>Vertices on a pyramid: {b("3em")}</p></div>'
    s1 += '</div></div>'

    # 2: Estimate First! review
    s2 = '<div class="abox" style="background:#fff3e0;">'\
         '<p><b>Estimate First!</b> A rectangular prism and a cube are glued together side by side. '\
         'Guess how many faces you could touch on the outside, then talk it through with your teacher.</p>'\
         '<p>My guess: ' + b("4em") + ' After discussing: ' + b("4em") + '</p></div>'

    # 3: Mixed review table (reduced from 6 to 3)
    s3 = '<p class="note">Review: fill in the table. Use a real object if it helps!</p>'
    s3 += '<table class="tbl"><tr><th>Solid</th><th>Picture</th><th>Faces</th><th>Edges</th><th>Vertices</th><th>Real-world example</th></tr>'
    for label, key in [("Cube", "cube"), ("Pyramid", "pyramid"), ("Cylinder", "cylinder")]:
        s3 += f'<tr><td>{label}</td><td style="text-align:center;">{SOLIDS[key](size=34)}</td>'\
              f'<td>{b("2.5em")}</td><td>{b("2.5em")}</td><td>{b("2.5em")}</td><td>{b("6em")}</td></tr>'
    s3 += '</table>'
    s3 += '<p style="font-size:11px; color:#666;">Hint for the cylinder: count only the FLAT faces.</p>'

    # 4: Word problem review
    s4 = '<div class="wp">'\
         '<p class="note">Read carefully. Show your work.</p>'\
         '<div class="abox"><p>Milo builds a tower with 3 cubes stacked on top of each other. '\
         'He wants to put a sticker on every face he can still SEE (the bottom of the tower and '\
         'the hidden faces between cubes don\'t count). How many stickers does he need?</p>'\
         '<p style="font-size:11px;">Draw or write your thinking: ' + bw() + '</p>'\
         '<p>' + b("3em") + ' stickers</p></div></div>'

    # 5: Self-check with emoji reflection
    s5 = '<div class="selfcheck">'\
         '<p><b>Self-Check: How do you feel about 3D shapes?</b></p>'\
         '<div style="display:flex; gap:20px; flex-wrap:wrap;">'\
         '<div style="background:#fff3e0; padding:10px; border-radius:5px; flex:1; min-width:150px;">'\
         '<p><b>Naming Solids</b></p>'\
         '<p>😊 I got it!  |  😐 Getting there  |  😟 Need help</p>'\
         '</div>'\
         '<div style="background:#e3f2fd; padding:10px; border-radius:5px; flex:1; min-width:150px;">'\
         '<p><b>Counting Faces, Edges & Vertices</b></p>'\
         '<p>😊 I got it!  |  😐 Getting there  |  😟 Need help</p>'\
         '</div>'\
         '<div style="background:#f3e5f5; padding:10px; border-radius:5px; flex:1; min-width:150px;">'\
         '<p><b>Matching Nets to Solids</b></p>'\
         '<p>😊 I got it!  |  😐 Getting there  |  😟 Need help</p>'\
         '</div>'\
         '</div>'\
         '<p style="margin-top:10px;"><b>One thing I learned this week:</b> ' + bl() + '</p>'\
         '<p><b>One thing I want to practice more:</b> ' + bl() + '</p>'\
         '<p><b>My favorite solid and where I saw one in real life:</b> ' + bl() + '</p>'\
         '</div>'

    return page(22, "Friday", "Week 22 Review & Self-Check",
        f'''{sec(1, "Warm-up: Solid Facts", s1)}
{sec(2, "Estimate First!", s2)}
{sec(3, "Faces, Edges & Vertices Review", s3)}
{sec(4, "Word Problem", s4)}
{sec(5, "Self-Check & Reflection", s5)}''')


# ═══════════════════════════════════════════════════
# TEACHER GUIDE
# ═══════════════════════════════════════════════════
def teacher_guide():
    return tg_page_multi(
        "Week 22", "3D Shapes — Teacher Guide",

        tg_section_title("Monday: Meet the 3D Shapes") +
        tg_sec(1, "Warm-up 2D Review", ["4, 3, 6, pentagon"]) +
        tg_sec(2, "The Six Solids", ["Vocabulary intro — no answers needed"]) +
        tg_sec(3, "Name That Solid", ["cone, cube, sphere, pyramid, cylinder"]) +
        tg_sec(4, "Number Talk", ["Sphere is curved all over; cube has flat faces that stop it", "Circle is flat (2D); sphere is solid (3D)"]) +
        tg_sec(5, "Word Problem", ["Cylinders and cones roll: 3+2 = 5"]) +
        tg_note("Page break"),

        tg_section_title("Tuesday: Faces, Edges & Vertices") +
        tg_sec(1, "Warm-up Riddles", ["sphere, cube, cylinder, cone"]) +
        tg_sec(2, "New Words", ["Cube: 6 faces, 12 edges, 8 vertices"]) +
        tg_sec(3, "Estimate First", ["Rect. prism: 6 faces; pyramid: 5 faces"]) +
        tg_sec(4, "Count Table", ["Cube 6/12/8; Rect prism 6/12/8; Pyramid 5/8/5; Sphere 0/0/0"]) +
        tg_sec(5, "Word Problem", ["6 faces ÷ 4 per pack → 2 packs, 2 stickers left over"]) +
        tg_note("Page break"),

        tg_section_title("Wednesday: Nets") +
        tg_sec(1, "Warm-up", ["6, 8, 0, 1"]) +
        tg_sec(2, "Match Nets", ["Cross net → cube; circles+rectangle → cylinder; square+4 triangles → pyramid"]) +
        tg_sec(3, "Two Ways", ["6 faces, not 5; all faces are squares, not triangles"]) +
        tg_sec(4, "Word Problems", ["6 rectangle faces", "4×3 = 12 triangles"]) +
        tg_sec(5, "Create Own Net", ["Any valid 6-square arrangement; encourage cut-and-fold test"]) +
        tg_note("Page break"),

        tg_section_title("Thursday: Real World") +
        tg_sec(1, "Warm-up Solid Math", ["12, 10, 11, 12−8=4"]) +
        tg_sec(2, "Real-World", ["sphere, cylinder, cone, rectangular prism, pyramid"]) +
        tg_sec(3, "2D and 3D", ["square, circle, square + triangles, circle"]) +
        tg_sec(4, "Number Talk", ["Same structure — prism is a stretched cube", "Cans — flat circle faces stack; spheres roll away"]) +
        tg_sec(5, "Word Problem & Hunt", ["5×2 = 10 circle faces; accept any correct household objects"]) +
        tg_note("Page break"),

        tg_section_title("Friday: Review & Self-Check") +
        tg_sec(1, "Warm-up", ["6, sphere, 12, 5"]) +
        tg_sec(2, "Estimate First", ["Discussion question — glued pair shows 10 outside faces"]) +
        tg_sec(3, "Review Table", ["Cube 6/12/8; Pyramid 5/8/5; Cylinder 2 flat faces, 0 edges/vertices (2nd-grade convention); examples vary"]) +
        tg_sec(4, "Word Problem", ["Tower of 3 cubes: 4 sides × 3 + 1 top = 13 stickers"]) +
        tg_sec(5, "Self-Check", ["Accept student self-assessment and reflection"])
    )


# ═══════════════════════════════════════════════════
# GENERATE
# ═══════════════════════════════════════════════════
if __name__ == "__main__":
    os.makedirs(WEEK, exist_ok=True)
    for f in glob.glob(os.path.join(WEEK, "*.pdf")):
        os.remove(f)
    for f in glob.glob(os.path.join(WEEK, "*.html")):
        os.remove(f)

    days = [
        (monday, "Monday", "Meet the 3D Shapes"),
        (tuesday, "Tuesday", "Faces, Edges & Vertices"),
        (wednesday, "Wednesday", "Nets: Unfolding Solids"),
        (thursday, "Thursday", "3D Shapes in the Real World"),
        (friday, "Friday", "Week 22 Review & Self-Check"),
    ]

    for lesson_func, day, title in days:
        html = lesson_func()
        fname = f"Week_22_{day}"
        path = os.path.join(WEEK, f"{fname}.html")
        with open(path, "w") as f:
            f.write(html)
        pdf_path = os.path.join(WEEK, f"{fname}.pdf")
        HTML(filename=path).write_pdf(pdf_path)
        print(f"Generated: {pdf_path}")

    html = teacher_guide()
    path = os.path.join(WEEK, "Week_22_Teacher_Guide.html")
    with open(path, "w") as f:
        f.write(html)
    pdf_path = os.path.join(WEEK, "Week_22_Teacher_Guide.pdf")
    HTML(filename=path).write_pdf(pdf_path)
    print(f"Generated: {pdf_path}")

    print("\nWeek 22 (new standard) complete!")
