#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
"""Create five original A4 vector aids; PDFs are exported from these SVGs."""
from __future__ import annotations

import html
import textwrap
from pathlib import Path

ROOT = Path(__file__).resolve().parent
INK = "#15384b"
TEAL = "#006878"
PALE = "#e8f4f2"
LINE = "#536d76"
FONT = "DejaVu Sans, sans-serif"


def esc(value: str) -> str:
    return html.escape(value, quote=True)


def text(x: float, y: float, value: str, size: float = 4, bold: bool = False, colour: str = INK) -> str:
    weight = ' font-weight="700"' if bold else ""
    return f'<text x="{x}" y="{y}" font-family="{FONT}" font-size="{size}"{weight} fill="{colour}">{esc(value)}</text>'


def wrapped(x: float, y: float, value: str, width: int, size: float = 4, gap: float = 6.2) -> str:
    return "\n".join(text(x, y + i * gap, line, size) for i, line in enumerate(textwrap.wrap(value, width=width)))


def rect(x: float, y: float, width: float, height: float, fill: str = "#fff", stroke: str = LINE, radius: float = 2) -> str:
    return f'<rect x="{x}" y="{y}" width="{width}" height="{height}" rx="{radius}" fill="{fill}" stroke="{stroke}" stroke-width=".8"/>'


def panel(x: float, y: float, width: float, height: float, label: str) -> str:
    return "\n".join(
        [
            rect(x, y, width, height),
            f'<rect x="{x}" y="{y}" width="{width}" height="12" fill="{PALE}"/>',
            text(x + 5, y + 8.3, label, 4.8, True),
        ]
    )


def page(title: str, description: str, heading: str, subtitle: str, body: str) -> str:
    start = (
        f'<svg xmlns="http://www.w3.org/2000/svg" width="210mm" height="297mm" viewBox="0 0 210 297" '
        f'role="img" aria-labelledby="title desc"><title id="title">{esc(title)}</title>'
        f'<desc id="desc">{esc(description)}</desc><rect width="210" height="297" fill="#fff"/>'
    )
    header = "\n".join(
        [
            text(14, 17, "SubjectNest  /  Foundation English  /  Weeks 39–40", 4.2, True, TEAL),
            text(14, 30, heading, 7.6, True),
            f'<path d="M14 37 H196" stroke="{TEAL}" stroke-width="1.2"/>',
            text(14, 46, subtitle, 3.8),
        ]
    )
    footer = "\n".join(
        [
            f'<path d="M14 277 H196" stroke="{LINE}" stroke-width=".6"/>',
            text(14, 286, "Point · say · sign · use AAC · move broad cards · direct an adult.", 3.3),
            text(14, 293, "Original SubjectNest vector  •  © 2026 NeuroForgeIO Pty Ltd  •  CC BY 4.0", 2.9),
        ]
    )
    return f"{start}\n{header}\n{body}\n{footer}\n</svg>\n"


def write(name: str, content: str) -> None:
    (ROOT / f"{name}.svg").write_text(content, encoding="utf-8")


kit_parts = [
    panel(14, 55, 57, 66, "TENT"),
    panel(76, 55, 58, 66, "POND"),
    panel(139, 55, 57, 66, "PATH"),
    '<path d="M28 104 L42 79 L56 104 Z" fill="#fff" stroke="#15384b" stroke-width="1.2"/>',
    rect(33, 104, 18, 10, "#fff", INK, 0),
    '<ellipse cx="105" cy="93" rx="18" ry="11" fill="#fff" stroke="#15384b" stroke-width="1.2"/>',
    '<path d="M151 111 Q157 84 161 78 M174 111 Q180 84 184 78" fill="none" stroke="#15384b" stroke-width="1.4"/>',
    panel(14, 128, 182, 136, "TO SHOW A NEW VISITOR"),
]
kit_steps = (
    "1  Choose one broad card from the SCENE pocket.",
    "2  Put it in the middle of the mat.",
    "3  Name its outline and label so a listener knows the card.",
    "4  Say if you describe the drawing or make up a story.",
    "5  Put the card back in the SCENE pocket.",
)
for y, step in zip((152, 174, 196, 218, 240), kit_steps, strict=True):
    kit_parts.append(wrapped(20, y, step, 77, 4.1, 6.5))
write(
    "story-kit-guide",
    page(
        "Paper scene kit guide with three outlined broad cards and five steps",
        "Three cards: TENT has a triangle roof above a rectangle; POND has one oval; PATH has two separate parallel curves. A SCENE pocket and plain mat are named. The guide says choose, place, name outline/label, distinguish drawing from invented story, then return card. No actual audience response is shown.",
        "Paper scene kit",
        "Three broad cards. One named pocket. Read steps in order.",
        "\n".join(kit_parts),
    ),
)

feedback_labels = (
    "AUDIENCE: REAL / FICTIONAL / PRIVATE",
    "FIRST WORDS OR FIRST CARD CHOICES",
    "SOURCE STEPS I USED",
    "ACTUAL LISTENER WORDS/ACTION · OR MODEL/NONE",
    "REVISED WORDS OR CHOICES",
    "STILL UNCLEAR OR NEXT TRY",
)
feedback_parts = [panel(14, 55 + index * 35, 182, 31, label) for index, label in enumerate(feedback_labels)]
write(
    "audience-feedback",
    page(
        "Blank audience, actual feedback and revision mat",
        "Six large blank fields: audience real/fictional/private; first words or choices; source steps; actual listener words/action or model/none; revised words or choices; still unclear or next try. A fictional listener question is never actual feedback.",
        "Who is this for? What changed?",
        "Record what really happened. Label a model as MODEL.",
        "\n".join(feedback_parts),
    ),
)

story_scenes = (
    "Mira drew a paper map of a pretend park for a paper puppet visitor. She marked a pond and a reading tent.",
    "When Mira opened the map, the tent label slid behind a flap. The puppet said, ‘I can see the pond, but I can't find the tent.’",
    "Mira lifted the flap, found the label and put it beside the tent drawing. She asked the puppet to try the map again.",
    "In the story, the puppet pointed to the tent and said, ‘There it is.’ Mira pressed the label flat so it would stay visible.",
)
story_parts = []
for index, (y, heading, scene) in enumerate(zip((55, 108, 161, 214), ("BEGINNING", "PROBLEM", "ACTION", "ENDING"), story_scenes, strict=True), start=1):
    story_parts.extend([panel(14, y, 182, 48, f"SCENE {index} · {heading}"), wrapped(20, y + 22, scene, 72, 4.0, 6.4)])
write(
    "story-sample",
    page(
        "Mira's map and the tent label, four-scene original fiction",
        "Four numbered scenes: Mira makes a pretend park map with pond and reading tent; TENT label slips behind a flap and a paper puppet cannot find it; Mira finds and replaces label; in the fictional ending the puppet points to tent. There is no real audience response.",
        "Mira's map and the tent label",
        "An original fictional story. Read all four scenes in order.",
        "\n".join(story_parts),
    ),
)

sample_parts = [panel(14, 55, 182, 111, "FUNCTIONAL SIGN · ADULT MAY READ")]
sign_lines = (
    "STORY CARD STATION",
    "Choose one broad scene card from the SCENE pocket.",
    "Place it on the mat.",
    "Say what the drawing shows, or make up a story and",
    "tell your listener it is pretend.",
    "Put the card back in the SCENE pocket.",
)
for index, line in enumerate(sign_lines):
    sample_parts.append(text(20, 83 + index * 13, line, 4.0, index == 0))
sample_parts.append(text(14, 178, "CONTROLLED PRINT · ONLY AT YOUR TAUGHT POINT", 4.1, True, TEAL))
for index, line in enumerate(("A map is on a mat.", "I can see a red cap.", "A cup is on a mat.")):
    y = 184 + index * 27
    sample_parts.extend([rect(14, y, 182, 24), text(20, y + 15, line, 5.0)])
write(
    "text-samples",
    page(
        "Functional station sign and three separate controlled print strips",
        "The rich functional sign says choose a broad scene card from SCENE pocket, put on mat, say what drawing shows or mark made-up story, return card. Three picture-free controlled strips read: A map is on a mat. I can see a red cap. A cup is on a mat. Adult reads rich sign; independent print evidence only when correspondences and familiar words are taught.",
        "A sign and short print strips",
        "Different purposes. Adult reads untaught words.",
        "\n".join(sample_parts),
    ),
)

portfolio_parts = []
for index, y in enumerate((55, 135), start=1):
    portfolio_parts.append(panel(14, y, 182, 75, f"ACTUAL SAMPLE {index}  ·  OR NOT AVAILABLE"))
    for sub_index, label in enumerate(("SOURCE + DATE:", "WHAT I DID MYSELF:", "ADULT HELP / WORDS:", "WHAT THIS SAMPLE SHOWS:")):
        portfolio_parts.append(text(20, y + 24 + sub_index * 14, label, 3.7, sub_index == 0))
        portfolio_parts.append(f'<path d="M86 {y+25+sub_index*14} H190" stroke="{LINE}" stroke-width=".5"/>')
portfolio_parts.extend(
    [
        panel(14, 215, 182, 49, "NEXT STEP · TEACHER MOVE · FEEDBACK STATUS"),
        text(20, 238, "MY NEXT TRY:", 3.7, True),
        text(20, 251, "TEACHER MOVE / ACTUAL FEEDBACK OR NONE:", 3.3),
    ]
)
write(
    "portfolio-handover",
    page(
        "Blank two-sample portfolio and next-step handover mat",
        "Two blank slots each ask source/date, child's own contribution, adult help/words and what the sample shows, with NOT AVAILABLE option. Last field asks child's next try, teacher move and actual feedback or none. No child profile, growth rating or evidence is prefilled.",
        "My actual work · my next try",
        "Use real dated samples. Name adult help. Missing stays missing.",
        "\n".join(portfolio_parts),
    ),
)
