#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
"""Build two original A4 Year 5 mathematics vector aids and PDF copies."""
from __future__ import annotations

import subprocess
from pathlib import Path
from xml.sax.saxutils import escape

HERE = Path(__file__).resolve().parent


def label(x: float, y: float, value: str, size: float = 4.6, bold: bool = False) -> str:
    return f'<text x="{x}" y="{y}" font-size="{size}" font-weight="{700 if bold else 400}">{escape(value)}</text>'


def rule(x: float, y: float, x2: float, weight: float = 0.35) -> str:
    return f'<path d="M{x} {y}H{x2}" stroke="#345269" stroke-width="{weight}"/>'


def box(x: float, y: float, w: float, h: float, fill: str = "#fffefa") -> str:
    return f'<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="2.5" fill="{fill}" stroke="#345269" stroke-width="0.55"/>'


def svg(title: str, desc: str, body: str) -> str:
    return f'''<svg xmlns="http://www.w3.org/2000/svg" width="210mm" height="297mm" viewBox="0 0 210 297" role="img" aria-labelledby="title desc">
<title id="title">{escape(title)}</title><desc id="desc">{escape(desc)}</desc>
<rect width="210" height="297" fill="#fffefa"/>
<g fill="#173b50" font-family="DejaVu Sans, sans-serif">{body}</g>
<text x="13" y="287" fill="#173b50" font-family="DejaVu Sans, sans-serif" font-size="3.4">SubjectNest · original classroom aid · CC BY 4.0 · neuroforge.io</text>
</svg>
'''


def products() -> str:
    out = [label(13, 17, "Partial products: tens + ones", 8, True),
           label(13, 26, "A useful model: 128 × 23 = 128 × (20 + 3)", 4.5),
           rule(13, 32, 197)]
    out += [box(13, 39, 184, 77, "#f1f6f8"), label(18, 50, "WORKED MODEL", 5.5, True),
            label(18, 64, "20 groups: 128 × 20 = 2 560", 5.2),
            label(18, 77, "3 groups:   128 × 3   =   384", 5.2), rule(18, 84, 192, 0.65),
            label(18, 96, "Together:  2 560 + 384 = 2 944", 5.4, True),
            label(18, 107, "Scale check: 128 × 20 alone is 2 560.", 4.3)]
    out += [label(13, 131, "MY NEW PROBLEM", 5.3, True), rule(67, 132, 197),
            box(13, 142, 184, 111, "#fffefa"),
            label(18, 153, "Tens groups (× 10, × 20, × 30, ...):", 4.6, True),
            rule(18, 164, 192), rule(18, 174, 192),
            label(18, 186, "Ones groups:", 4.6, True), rule(18, 196, 192), rule(18, 206, 192),
            label(18, 218, "Combine equal units:", 4.6, True), rule(18, 229, 192),
            label(18, 241, "Does the result fit my estimate?", 4.6, True), rule(18, 249, 192),
            label(13, 266, "Say why a zero in the tens row has place value.", 4.2)]
    return svg("Year 5 partial-products mat", "Worked example 128 times 23 split into 20 groups and 3 groups, then blank labelled spaces for a new tens product, ones product, sum and scale check. Full text and tactile build in TEXT-ALTERNATIVES.md.", "\n".join(out))


def decision() -> str:
    out = [label(13, 17, "Estimate → exact → decide", 8, True),
           label(13, 26, "Use the given unit and constraint. Do not guess missing facts.", 4.4), rule(13, 32, 197)]
    entries = [
        ("1 · QUESTION + COMMON UNIT", "What is being counted or priced?", "#f1f6f8"),
        ("2 · REASONABLE BENCHMARK", "Round and say whether it is high or low.", "#f1f8f2"),
        ("3 · EXACT PRODUCT", "Show partial products or another clear method.", "#fff7eb"),
        ("4 · LIMIT + DECISION", "Compare in the same unit. What remains unknown?", "#f6f2fa"),
    ]
    for i, (heading, prompt, colour) in enumerate(entries):
        y = 40 + i * 55
        out += [box(13, y, 184, 49, colour), label(18, y+10, heading, 5, True),
                label(18, y+19, prompt, 4), rule(18, y+31, 192), rule(18, y+42, 192)]
    out += [label(13, 268, "A calculator answer still needs a scale and context check.", 4.2)]
    return svg("Year 5 estimate exact decide mat", "Four numbered, labelled boxes in reading order: question/common unit, reasonable benchmark, exact product, limit/decision. Each has blank writing lines. Full text and tactile build in TEXT-ALTERNATIVES.md.", "\n".join(out))


def main() -> None:
    for stem, content in (("partial-products-mat", products()), ("estimate-exact-decision", decision())):
        path = HERE / f"{stem}.svg"
        path.write_text(content, encoding="utf-8")
        subprocess.run(["rsvg-convert", "-f", "pdf", "-o", str(path.with_suffix(".pdf")), str(path)], check=True)
        print(path.name, path.with_suffix(".pdf").name)


if __name__ == "__main__":
    main()
