#!/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 33–34", 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")


plant_body = "\n".join(
    [
        panel(14, 55, 87, 211, "DRAWING P"),
        panel(109, 55, 87, 211, "DRAWING Q"),
        f'<path d="M57 93 V213 M152 93 V213" stroke="{TEAL}" stroke-width="1.6"/>',
        f'<path d="M57 111 L45 107 M57 146 L71 141 M57 179 L44 174" stroke="{TEAL}" stroke-width="1.3"/>',
        f'<ellipse cx="43" cy="105" rx="14" ry="7" fill="white" stroke="{TEAL}" stroke-width="1.2"/>',
        f'<ellipse cx="73" cy="139" rx="14" ry="7" fill="white" stroke="{TEAL}" stroke-width="1.2"/>',
        f'<ellipse cx="42" cy="171" rx="14" ry="7" fill="white" stroke="{TEAL}" stroke-width="1.2"/>',
        f'<path d="M152 130 L139 125 M152 171 L170 166" stroke="{TEAL}" stroke-width="1.3"/>',
        f'<ellipse cx="135" cy="123" rx="13" ry="3.5" fill="white" stroke="{TEAL}" stroke-width="1.2" transform="rotate(-18 135 123)"/>',
        f'<ellipse cx="174" cy="165" rx="13" ry="3.5" fill="white" stroke="{TEAL}" stroke-width="1.2" transform="rotate(18 174 165)"/>',
        f'<ellipse cx="57" cy="216" rx="27" ry="10" fill="{PALE}" stroke="{TEAL}" stroke-width="1.2"/>',
        rect(128, 207, 48, 24, PALE, TEAL, 0),
        text(20, 244, "1 stem · 3 oval leaves", 3.9, True),
        text(20, 252, "round pot", 3.9),
        text(115, 244, "1 stem · 2 narrow leaves", 3.8, True),
        text(115, 252, "square pot", 3.9),
        text(20, 262, "Invented drawing", 3.2),
        text(115, 262, "Invented drawing", 3.2),
    ]
)
write(
    "plant-observation",
    page(
        "Two invented drawn plants with visible feature descriptions",
        "Two side-by-side broad observation cards. P has one visible straight stem, three separate oval leaf outlines and round pot. Q has one visible straight stem, two narrow leaf outlines and square pot. Neither is a real species or local observation.",
        "What can the drawing show?",
        "Describe lines you can point to. Leave growth, needs and place unknown.",
        plant_body,
    ),
)

info_body = "\n".join(
    [
        panel(14, 55, 182, 30, "TITLE"),
        panel(14, 91, 182, 30, "SOURCE · drawing or actual dated observation?"),
        panel(14, 127, 87, 53, "DETAIL 1 · source clue"),
        panel(109, 127, 87, 53, "DETAIL 2 · source clue"),
        panel(14, 186, 87, 83, "PICTURE OR CAPTION"),
        panel(109, 186, 87, 83, "STILL TO FIND OUT"),
    ]
)
write(
    "information-page",
    page(
        "Short information page with source and unknown fields",
        "A4 six-area blank information-page mat. Read top to bottom: title; source; detail one and detail two; picture or caption; still to find out. Broad boxes allow writing, drawing, tactile cards and child-directed scribing. No answer is prefilled.",
        "Make a short information page",
        "What does your source show? Which question stays open?",
        info_body,
    ),
)

roof_report = (
    "Ari put two small cardboard blocks the same distance apart. Ari laid a tissue-paper strip "
    "across the gap as a roof and placed one broad cardboard disk on it. In this report the tissue tore. "
    "Ari put a card strip of the same length across the same gap and used the same disk. In this report "
    "the card stayed whole. Ari did not try a second disk or test a different gap."
)
roof_body = "\n".join(
    [
        panel(14, 55, 87, 122, "TRY 1 · TISSUE"),
        panel(109, 55, 87, 122, "TRY 2 · CARD"),
        rect(23, 117, 16, 35, PALE, TEAL),
        rect(76, 117, 16, 35, PALE, TEAL),
        rect(118, 117, 16, 35, PALE, TEAL),
        rect(171, 117, 16, 35, PALE, TEAL),
        f'<path d="M39 116 H76" stroke="{TEAL}" stroke-width="1.2"/>',
        f'<rect x="134" y="113" width="37" height="4" fill="{PALE}" stroke="{TEAL}" stroke-width="1.2"/>',
        f'<ellipse cx="57.5" cy="104" rx="15" ry="5" fill="white" stroke="{TEAL}" stroke-width="1.2"/>',
        f'<ellipse cx="152.5" cy="104" rx="15" ry="5" fill="white" stroke="{TEAL}" stroke-width="1.2"/>',
        text(34, 86, "same broad disk", 3.4),
        text(129, 86, "same broad disk", 3.4),
        text(33, 166, "Reported: tore", 3.8, True),
        text(126, 166, "Reported: stayed whole", 3.6, True),
        text(14, 190, "Original adult-read fictional report", 4.3, True),
        wrapped(14, 201, roof_report, 94, 3.25, 5.4),
    ]
)
write(
    "roof-test",
    page(
        "Fictional one-trial paper roof record",
        "Two pictured paper strips of the same length over blocks at the same gap, each shown with the same broad disk. The full adult-read report says tissue tore and card stayed whole in one fictional trial. A second disk and a different gap were not tried. Drawings do not demonstrate actual material strength.",
        "One reported paper-roof trial",
        "Same gap and disk · different material · only one described result",
        roof_body,
    ),
)

explanation_one = "The card roof is always best because it looks thick."
explanation_two = (
    "In Ari's one reported test, the tissue tore under the broad disk and the card stayed whole "
    "with the same disk and gap. The card suited that tested roof purpose in that trial. "
    "Another load or gap has not been checked."
)
explanation_body = "\n".join(
    [
        panel(14, 55, 182, 87, "EXPLANATION 1"),
        wrapped(22, 80, explanation_one, 72, 5, 8.5),
        panel(14, 150, 182, 116, "EXPLANATION 2"),
        wrapped(22, 173, explanation_two, 74, 4.3, 7),
        text(22, 256, "Which exact part of the report supports a claim?", 3.8),
    ]
)
write(
    "explanation-cards",
    page(
        "Two competing explanations of a fictional roof report",
        "A4 page with two equal-style explanation cards. One claims card is always best because it looks thick. The other confines the conclusion to Ari's single reported disk and gap and states another load or gap was not checked. Neither card is visually marked right or wrong.",
        "Which explanation fits the source?",
        "Read both in the same voice. Find the clue, then name a limit.",
        explanation_body,
    ),
)

compare_body = "\n".join(
    [
        panel(14, 55, 182, 65, "CLAIM · what are you saying?"),
        panel(14, 127, 182, 65, "SOURCE OR ACTUAL OBSERVATION · what supports it?"),
        panel(14, 199, 182, 65, "STILL TO TEST · what remains unknown?"),
    ]
)
write(
    "claim-evidence-question",
    page(
        "Claim, source or observation, and still to test mat",
        "A4 blank three-area mat read top to bottom: claim; source or actual observation that supports it; still to test. Every area is large enough for a broad tactile card, point, drawing, dictated or written response. No colour alone carries meaning.",
        "Claim · source · next question",
        "Put a reported result apart from a prediction or an unrun test.",
        compare_body,
    ),
)
print("Generated 5 original A4 SVGs")
