#!/usr/bin/env python3
"""
Thursday Generator - Word Parts & Meaning Phase (Write It, 4 pages)
Usage:
from thursday_wp import generate_thursday
generate_thursday(week_dir=..., week_num=..., topic_label=..., words=..., ...)
"""
import os, sys, random
sys.path.insert(0, os.path.dirname(__file__))
from helpers import CSS, header, sectitle, secnote, write_line, page_break, remember_box
from weasyprint import HTML
def generate_thursday(**kw):
week_dir = kw["week_dir"]
week_num = kw["week_num"]
day_name = kw.get("day_name", "Thursday")
topic_label = kw["topic_label"]
words = kw["words"]
learning_text = kw["learning_text"]
remember_text = kw["remember_text"]
story_text = kw["story_text"]
comp_questions = kw["comp_questions"]
sentence_sort_data = kw.get("sentence_sort_data", [])
detective_words = kw.get("detective_words", []) # [misspelled_word, ...]
swap_data = kw.get("swap_data", [])
map_word = kw["map_word"]
para_prompts = kw.get("para_prompts", [])
story_prompt = kw.get("story_prompt", "Write a story using at least 5 of your spelling words.")
# New: Build words activity
build_words = kw.get("build_words", []) # [(base, affix, meaning_hint), ...]
# Configurable labels for prefix vs suffix
word_part_type = kw.get("word_part_type", "prefix") # "prefix" or "suffix"
build_word_label = kw.get("build_word_label", f"{word_part_type.capitalize()}")
build_word_note = kw.get("build_word_note", f"Combine the {word_part_type} and base word. Write the new word.")
day_dir = os.path.join(week_dir, "Thursday")
os.makedirs(day_dir, exist_ok=True)
WORD_NAMES = [w[0] for w in words]
# Comprehension questions
comp_html = "".join(f'<div style="margin-bottom:8px;"><strong style="font-size:12px;">{q}</strong><br>{write_line()}</div>' for q in comp_questions)
# Sentence Sort
sort_html = ""
for idx, sentence in enumerate(sentence_sort_data, 1):
word_list = sentence.split()
shuffled = list(word_list)
random.Random(50 + idx).shuffle(shuffled)
tags = "".join(f'<span style="display:inline-block;background:#FFF3E0;border:1px solid #FFB74D;padding:2px 8px;margin:2px;border-radius:3px;font-size:11px;">{w}</span>' for w in shuffled)
sort_html += f'<div style="margin:8px 0;padding:6px 8px;background:#FAFAFA;border:1.5px solid #B2DFDB;border-radius:6px;"><div style="font-size:11px;font-weight:bold;color:#FF7043;margin-bottom:4px;">Sentence {idx}:</div><div style="margin-bottom:4px;">{tags}</div>{write_line()}</div>'
# Spelling Detective
det_html = ""
for wrong in detective_words:
det_html += f'<div style="display:inline-block;width:30%;margin:4px;padding:4px 8px;background:#FFF8E1;border-radius:4px;border:1px solid #FFD54F;font-size:12px;"><span style="text-decoration:line-through;color:#E53935;">{wrong}</span> <span style="color:#888;">→</span> <div style="position:relative;height:18px;margin:2px 0;display:inline-block;width:100%"><div style="position:absolute;left:0;right:0;top:0;border-top:0.6pt solid rgb(0,0,255)"></div><div style="position:absolute;left:0;right:0;bottom:12px;border-bottom:0.4pt dashed rgb(255,0,0)"></div><div style="position:absolute;left:0;right:0;bottom:0;border-bottom:0.6pt solid rgb(0,0,255)"></div></div></div>'
# Word Swap
swap_html = ""
for orig, (w1o, w1s), (w2o, w2s) in swap_data:
highlighted = orig.replace(w1o, f"<strong>{w1o}</strong>").replace(w2o, f"<strong>{w2o}</strong>")
swap_html += f'<div style="margin-bottom:10px;padding:6px 8px;background:#FFF3E0;border-radius:5px;border:1px solid #FFB74D;"><div style="font-size:10.5px;font-weight:bold;color:#FF7043;margin-bottom:3px;">Original:</div><div style="font-size:12px;font-style:italic;margin-bottom:4px;">{highlighted}</div><div style="font-size:10.5px;font-weight:bold;color:#FF7043;margin-bottom:3px;">Now write using <strong>{w1s}</strong> and <strong>{w2s}</strong>:</div>{write_line()}</div>'
# Word Parts Map (adapted from Spelling Map)
def map_line():
return '<div style="position:relative;height:22px;margin:2px 0;"><div style="position:absolute;left:0;right:0;top:0;border-top:0.6pt solid rgb(0,0,255)"></div><div style="position:absolute;left:0;right:0;bottom:12px;border-bottom:0.4pt dashed rgb(255,0,0)"></div><div style="position:absolute;left:0;right:0;bottom:0;border-bottom:0.6pt solid rgb(0,0,255)"></div></div>'
map_html = (f'<div style="text-align:center;margin:12px 0;padding:12px;background:#E8F5E9;border-radius:8px;border:2px solid #A5D6A7;">'
f'<div style="font-weight:bold;font-size:14px;color:#2E7D32;margin-bottom:8px;">{map_word}</div>'
f'<table style="margin:0 auto;border-collapse:separate;border-spacing:4px;width:auto;">'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">Meaning:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">{build_word_label}:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">Base word:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">Sentence:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'</table></div>')
# Paragraph Builder
para_html = ""
for p in para_prompts:
para_html += f'<div style="margin:8px 0;padding:6px 8px;background:#E0F2F1;border:1.5px solid #80CBC4;border-radius:6px;"><div style="font-size:11px;font-weight:bold;color:#FF7043;margin-bottom:4px;">{p}</div>{write_line()}{write_line()}{write_line()}</div>'
# Build Words activity
build_html = ""
if build_words:
build_items = ""
for base, affix, hint in build_words:
build_items += f'<div style="margin:6px 0;font-size:12px;"><strong style="color:#26A69A;">{affix}</strong> + <strong style="color:#FF7043;">{base}</strong> = <span style="color:#888;font-style:italic;">(means: {hint})</span><br>{write_line()}</div>'
build_html = f'{sectitle("Build the Word")}{secnote(build_word_note)}{build_items}'
safe_label = topic_label.replace(' ', '_')
pdf_name = f"Week0{week_num}_{day_name}_{safe_label}.pdf"
html = f"""<!DOCTYPE html>
<html><head><meta charset="utf-8"><style>{CSS}</style></head><body>
<div>
{header("English Language Arts", f"Week {week_num}, {day_name} -- Write It")}
{sectitle("Here's What We're Learning")}
{secnote(learning_text)}
{remember_box("Remember This!", remember_text)}
{sectitle("Spelling Story")}
{secnote("Read the story. Circle each spelling word.")}
<div class="story-box">{story_text}</div>
{sectitle("Comprehension Questions")}
{secnote("Answer each question in a complete sentence.")}
{comp_html}
</div>
{page_break()}
<div>
{sectitle("Sentence Sort")}
{secnote("Unscramble the words to form correct sentences.")}
{sort_html}
{sectitle("Spelling Detective")}
{secnote("Each word has a mistake. Write the correct spelling.")}
{det_html}
{page_break()}
{build_html}
{sectitle("Word Swap")}
{secnote("Read the original, then write your own using the new words.")}
{swap_html}
</div>
<div>
{sectitle("Word Parts Map")}
{secnote("Fill in the details for this week's featured word.")}
{map_html}
{page_break()}
{sectitle("Paragraph Builder")}
{secnote("Write a short paragraph for each prompt. Use at least 2 spelling words in each.")}
{para_html}
</div>
<div>
{sectitle("Write Your Own Story")}
{secnote("Write a story using at least 5 of your spelling words. Use capital letters and periods!")}
<div style="font-size:11px;font-weight:bold;color:#FF7043;margin-bottom:8px;">{story_prompt}</div>
{write_line()}
{write_line()}
{write_line()}
{write_line()}
{write_line()}
{write_line()}
{write_line()}
{write_line()}
</div>
</body></html>"""
HTML(string=html).write_pdf(os.path.join(day_dir, pdf_name))
print(f"[ok] Week {week_num} Thursday generated")