#!/usr/bin/env python3
"""Generate original, searchable A4 Year 9 English aids from SVG."""

from __future__ import annotations

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

HERE = Path(__file__).resolve().parent
INK, BLUE, GREY = "#17212b", "#145d78", "#425669"


def t(x: int, y: int, value: str, size: int = 19, weight: int = 400,
      colour: str = INK, anchor: str = "start") -> str:
    return (f'<text x="{x}" y="{y}" fill="{colour}" font-family="DejaVu Sans, sans-serif" '
            f'font-size="{size}" font-weight="{weight}" text-anchor="{anchor}">{escape(value)}</text>')


def b(x: int, y: int, w: int, h: int, fill: str = "white", stroke: str = INK,
      rad: int = 10, sw: int = 2) -> str:
    return (f'<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="{rad}" '
            f'fill="{fill}" stroke="{stroke}" stroke-width="{sw}"/>')


def l(x1: int, y1: int, x2: int, y2: int, sw: int = 2, colour: str = INK) -> str:
    return f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" stroke="{colour}" stroke-width="{sw}"/>'


def page(title: str, desc: str, body: list[str], footer: str) -> str:
    head = ['<svg xmlns="http://www.w3.org/2000/svg" width="210mm" height="297mm" viewBox="0 0 794 1123" role="img">',
            f'<title>{escape(title)}</title>', f'<desc>{escape(desc)}</desc>',
            '<rect width="794" height="1123" fill="white"/>',
            b(34, 26, 726, 98, fill="#e9f3f6", stroke=BLUE),
            t(54, 64, "SUBJECTNEST / YEAR 9 / ENGLISH", 16, 700, BLUE),
            t(54, 103, title, 28, 700)]
    foot = [l(34, 1074, 760, 1074, colour=GREY),
            t(40, 1100, footer, 13, colour=GREY), '</svg>']
    return "\n".join(head + body + foot) + "\n"


def cohesion() -> str:
    out = [t(40, 162, "A clear link names the relationship, not a guess.", 20, 700),
           t(40, 193, "Read in numbered order; the words carry all information.", 16)]
    cards = [
        ("1  ACTOR + ACTION", "At 9:20, the crew moved the arrow."),
        ("2  WARRANTED LINK", "because a table blocked the door view"),
        ("3  CLEAR REFERENCE", "The sign change = the move above"),
        ("4  BOUNDED ENDING", "A second arrow was added; its effect is unknown."),
    ]
    for i, (head, sentence) in enumerate(cards):
        y = 230 + 176 * i
        out += [b(55, y, 684, 143), b(69, y + 12, 656, 47, fill="#e9f3f6", stroke=BLUE),
                t(86, y + 44, head, 18, 700, BLUE), t(86, y + 95, sentence, 19)]
        if i < 3:
            out += [l(397, y + 144, 397, y + 166, colour=BLUE),
                    f'<polygon points="389,{y + 160} 405,{y + 160} 397,{y + 172}" fill="{BLUE}"/>']
    out += [b(40, 953, 714, 95, fill="#fafcfd", stroke=BLUE),
            t(57, 987, "TEST A CONNECTIVE", 18, 700, BLUE),
            t(57, 1023, "time • reason • contrast • result: which is supported?", 17)]
    return page("Cohesion chain",
                "Four vertical numbered cards: actor and action, warranted connective, clear reference, bounded ending. The example uses the fictional arrow move. A final box asks whether a time, reason, contrast or result relation is supported.",
                out, "Original A4 editing model • complete text/tactile route alongside")


def agency() -> str:
    out = [t(40, 163, "A noun can summarise an action. Check what it hides.", 20, 700),
           t(40, 195, "Example from the invented route log:", 16),
           b(40, 217, 714, 188, fill="#fafcfd", stroke=BLUE),
           t(60, 257, "Actor + action", 18, 700, BLUE),
           t(60, 292, "The crew moved the arrow.", 19),
           t(60, 333, "Useful short reference", 18, 700, BLUE),
           t(60, 369, "The move / the sign change (after action is clear)", 17),
           t(40, 448, "ASK FOUR QUESTIONS BEFORE CONDENSING", 19, 700)]
    labels = [
        ("1  Who acted?", "____________________________________________"),
        ("2  What happened?", "____________________________________________"),
        ("3  Which summary noun names that action?", "____________________________________________"),
        ("4  What does the source NOT establish?", "____________________________________________"),
    ]
    for i, (head, blank) in enumerate(labels):
        y = 467 + i * 135
        out += [b(40, y, 714, 119), t(57, y + 41, head, 18, 700, BLUE),
                t(57, y + 86, blank, 18)]
    out += [t(40, 1045, "Use a noun to guide the reader, not to invent a result.", 17, 700)]
    return page("Agency + abstract noun lens",
                "Top example shows crew moved the arrow then the compact references the move or the sign change. Four large blank numbered prompts ask who acted, what happened, which noun summarises it and what the source does not establish.",
                out, "Original A4 actor/action scaffold • full text/tactile route alongside")


def editor() -> str:
    out = [t(40, 163, "Edit for a reader who missed the original source.", 20, 700),
           t(40, 194, "Keep the old line so the reason for your edit is visible.", 16),
           b(40, 220, 714, 68, fill="#e9f3f6", stroke=BLUE),
           t(57, 264, "SOURCE / AUDIENCE: ______________________________", 18, 700, BLUE)]
    for x, label in ((40, "BEFORE: exact draft words"), (407, "AFTER: your revision")):
        out += [b(x, 311, 347, 430), b(x + 11, 323, 325, 48, fill="#e9f3f6", stroke=BLUE),
                t(x + 20, 355, label, 17, 700, BLUE)]
        for i in range(7):
            y = 411 + i * 45
            out.append(l(x + 19, y, x + 327, y, colour=GREY))
    out += [b(40, 771, 714, 281, fill="#fafcfd", stroke=BLUE),
            t(57, 807, "EDIT CHECK: point to a line in each version", 18, 700, BLUE),
            t(57, 852, "1  Actor/action named? ______________________________", 17),
            t(57, 897, "2  Reference has one clear anchor? ____________________", 17),
            t(57, 942, "3  Connective shows a supported link? _________________", 17),
            t(57, 987, "4  Outcome or interpretation honestly limited? _________", 17),
            t(57, 1033, "Effect on intended reader: __________________________", 17)]
    return page("Two-version editor",
                "Blank A4 editor. Top source/audience line. Two side-by-side seven-line panels labelled before exact draft words and after your revision. Lower checklist asks actor/action, anchored reference, warranted connective, bounded outcome or interpretation, and intended reader effect.",
                out, "Original A4 revision sheet • full text/tactile route alongside")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--write", action="store_true")
    args = parser.parse_args()
    if not args.write:
        parser.error("pass --write to regenerate three A4 aid pairs")
    env = {**os.environ, "SOURCE_DATE_EPOCH": "1790640000"}  # 2026-09-29 UTC.
    for stem, build in (("cohesion-chain", cohesion), ("agency-lens", agency),
                        ("two-version-editor", editor)):
        svg, pdf = HERE / f"{stem}.svg", HERE / f"{stem}.pdf"
        svg.write_text(build(), encoding="utf-8")
        subprocess.run(["rsvg-convert", "--format", "pdf", "--output", str(pdf), str(svg)],
                       check=True, env=env)
        print(f"generated {svg.name} + {pdf.name}")


if __name__ == "__main__":
    main()
