#!/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 37–38", 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")


shape_parts = [text(20, 55, "ONE OUTLINED SHAPE = ONE PRETEND PAPER CARD", 4.0, True)]
for y, label, count, shape in (
    (61, "CIRCLE", 6, "circle"),
    (125, "SQUARE", 4, "square"),
    (189, "TRIANGLE", 2, "triangle"),
):
    shape_parts.extend([panel(14, y, 182, 55, label), text(20, y + 46, f"Count each separate outline in the {label.lower()} row.", 3.5)])
    for index in range(count):
        x, cy = 84 + index * (25 if shape == "triangle" else 17), y + 27
        if shape == "circle":
            shape_parts.append(f'<circle cx="{x}" cy="{cy}" r="7" fill="#fff" stroke="{INK}" stroke-width="1.2"/>')
        elif shape == "square":
            shape_parts.append(rect(x - 7, cy - 7, 14, 14, "#fff", INK, 0))
        else:
            shape_parts.append(f'<path d="M{x} {cy-8} L{x-8} {cy+7} L{x+8} {cy+7} Z" fill="#fff" stroke="{INK}" stroke-width="1.2"/>')
shape_parts.append(wrapped(16, 256, "Fictional tray. These counts do not tell us what any child likes or which shape is best.", 84, 3.8, 6.0))
write(
    "shape-tray-data",
    page(
        "Fictional tray: one outlined symbol is one paper card",
        "Three labelled rows: CIRCLE has six separate outlined circles; SQUARE has four separate outlined squares; TRIANGLE has two separate outlined triangles. Total twelve. The tray is invented and does not report anyone's preferences.",
        "Paper shape inventory",
        "Read labels. Count one separate outline as one pretend card.",
        "\n".join(shape_parts),
    ),
)

question_parts = []
for index, (y, question) in enumerate(
    zip(
        (55, 108, 161, 214),
        (
            "Which shape has the most paper cards in this pretend tray?",
            "How many triangle cards are shown?",
            "Which shape is best?",
            "Do all children like circles?",
        ),
        strict=True,
    ),
    start=1,
):
    question_parts.extend([panel(14, y, 182, 48, f"QUESTION {index}"), wrapped(20, y + 25, question, 70, 4.5, 7)])
write(
    "question-cards",
    page(
        "Four source questions without answers marked",
        "Four equally styled cards ask: which shape has most paper cards; how many triangle cards; which shape is best; and do all children like circles. The first two can be answered from the fictional paper inventory. The latter two need purpose or other evidence. No answer cue is printed on cards.",
        "Can this source answer it?",
        "Read each question. Point, say, sign or select a reason.",
        "\n".join(question_parts),
    ),
)

report_labels = (
    "QUESTION",
    "SOURCE",
    "WHAT THE DATA SAYS",
    "ANSWER WITH A CLUE",
    "WHAT THIS DOES NOT TELL US",
)
report_parts = [panel(14, 55 + index * 43, 182, 38, label) for index, label in enumerate(report_labels)]
write(
    "data-report",
    page(
        "Blank five-field source-bounded data report mat",
        "Five large blank fields in order: QUESTION, SOURCE, WHAT THE DATA SAYS, ANSWER WITH A CLUE, WHAT THIS DOES NOT TELL US. Each field can receive speech, AAC selection, adult scribing, drawing or broad tokens.",
        "A tiny report with its clue",
        "Use your own answer. Leave unknowns as unknowns.",
        "\n".join(report_parts),
    ),
)

plant_parts = [panel(14, 55, 88, 190, "MOCK DRAWING A"), panel(108, 55, 88, 190, "MOCK DRAWING B")]
for stem_x in (58, 152):
    plant_parts.append(f'<path d="M{stem_x} 210 L{stem_x} 112" fill="none" stroke="{INK}" stroke-width="1.6"/>')
    plant_parts.append(f'<path d="M{stem_x-25} 211 H{stem_x+25}" fill="none" stroke="{LINE}" stroke-width="1.0"/>')
for cx, cy in ((43, 157), (73, 139), (137, 157), (167, 139), (137, 118)):
    plant_parts.append(f'<ellipse cx="{cx}" cy="{cy}" rx="13" ry="7" fill="#fff" stroke="{INK}" stroke-width="1.2"/>')
plant_parts.extend(
    [
        text(32, 231, "Two oval leaf outlines", 3.8),
        text(124, 231, "Three oval leaf outlines", 3.8),
        wrapped(16, 258, "Invented drawings. No date, real plant identity or growth is recorded.", 85, 3.7, 6.0),
    ]
)
write(
    "mock-plant-pair",
    page(
        "Two mock plant drawings with different leaf-outline counts",
        "Mock drawing A has one straight stem and two separate oval leaf outlines. Mock drawing B has one straight stem and three separate oval leaf outlines. Both are invented, undated drawings. They do not establish that one real plant grew.",
        "Two mock plant drawings",
        "Compare marks on paper. Do not call these real observations.",
        "\n".join(plant_parts),
    ),
)

edit_labels = (
    "FIRST CLAIM",
    "SOURCE",
    "WHAT IS ACTUALLY SHOWN",
    "REVISED CLAIM",
    "STILL TO CHECK",
)
edit_parts = [panel(14, 55 + index * 43, 182, 38, label) for index, label in enumerate(edit_labels)]
write(
    "fact-check-edit",
    page(
        "Blank five-field source/claim editing mat",
        "Five large blank fields in order: FIRST CLAIM, SOURCE, WHAT IS ACTUALLY SHOWN, REVISED CLAIM, STILL TO CHECK. Child can direct an adult, point, use AAC, draw, dictate or write. The mat has no prefilled answer.",
        "Check a claim before sharing",
        "Use the source. Keep first and revised words.",
        "\n".join(edit_parts),
    ),
)
