"""Regenerate the styled estimate plot from the visual-reading CSV.

All means and interval endpoints are approximate readings from NASA slide 10,
not numerical source data. This script reproduces the illustration, not the
underlying measurements or confidence-interval calculation.
"""
import csv
from pathlib import Path

ROOT = Path(__file__).resolve().parent
CSV = ROOT / "mean-thrust-95ci-visual-reading.csv"


def read_rows():
    with CSV.open(encoding="utf-8", newline="") as stream:
        rows = list(csv.DictReader(stream))
    if [row["thruster"] for row in rows] != ["ETU-2", "TDU-1", "TDU-3"]:
        raise ValueError("Unexpected categories in visual-reading CSV")
    return [
        (
            row["thruster"],
            float(row["mean_thrust_mN_approx_visual_reading"]),
            float(row["lower_95_percent_CI_mN_approx_visual_reading"]),
            float(row["upper_95_percent_CI_mN_approx_visual_reading"]),
            color,
            marker,
        )
        for row, color, marker in zip(
            rows,
            ("#70d6ff", "#f15bb5", "#ffc857"),
            ("circle", "square", "diamond"),
        )
    ]


def make_svg(wide, rows):
    if wide:
        width, height = 1080, 740
        left, right, top, bottom = 145, 1010, 122, 520
        xs = (335, 577, 819)
        title = "Approximate visual redraw of 95% mean-thrust intervals"
    else:
        width, height = 700, 760
        left, right, top, bottom = 122, 670, 145, 570
        xs = (250, 405, 560)
        title = "Approximate visual redraw - mean-thrust intervals"

    def y(value):
        return bottom - (value - 608) * ((bottom - top) / 6)

    lines = [
        f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" role="img" aria-labelledby="title desc">',
        '<title id="title">NASA AEPS ETU-2 presentation: approximate 95% confidence intervals for mean thrust</title>',
        '<desc id="desc">A style redraw of slide 10, for an indicated contingency operating condition of 630 volts and 13.1 kilowatts. Approximate visual readings show ETU-2 near 611.5 millinewtons, TDU-1 near 610.1, and TDU-3 near 611.5. Each has a vertical whisker labelled 95% confidence interval. The y axis is truncated from 608 to 614 millinewtons, so small differences look larger. Exact means, interval endpoints, sample counts and calculation method are not provided as data.</desc>',
        f'<rect width="{width}" height="{height}" rx="22" fill="#0c1930"/>',
        f'<text x="{width / 2}" y="42" fill="#f3f6ff" font-family="Arial,sans-serif" font-size="{24 if wide else 22}" font-weight="700" text-anchor="middle">{title}</text>',
        f'<text x="{width / 2}" y="77" fill="#aebedc" font-family="Arial,sans-serif" font-size="{18 if wide else 17}" text-anchor="middle">Slide context: 630 V / 13.1 kW contingency condition</text>',
    ]
    for tick in range(608, 615):
        yy = y(tick)
        lines.append(f'<line x1="{left}" y1="{yy:.1f}" x2="{right}" y2="{yy:.1f}" stroke="#344b70" stroke-width="1"/>')
        lines.append(f'<text x="{left - 16}" y="{yy + 7:.1f}" fill="#edf3ff" font-family="Arial,sans-serif" font-size="19" text-anchor="end">{tick}</text>')
    lines.extend((
        f'<line x1="{left}" y1="{top}" x2="{left}" y2="{bottom}" stroke="#b7c6e2" stroke-width="2"/>',
        f'<line x1="{left}" y1="{bottom}" x2="{right}" y2="{bottom}" stroke="#b7c6e2" stroke-width="2"/>',
    ))
    for x, row in zip(xs, rows):
        name, mean, low, high, color, marker = row
        y_low, y_high, y_mean = y(low), y(high), y(mean)
        cap = 25 if wide else 21
        lines.extend((
            f'<line x1="{x}" y1="{y_high:.1f}" x2="{x}" y2="{y_low:.1f}" stroke="{color}" stroke-width="6"/>',
            f'<line x1="{x-cap}" y1="{y_high:.1f}" x2="{x+cap}" y2="{y_high:.1f}" stroke="{color}" stroke-width="6"/>',
            f'<line x1="{x-cap}" y1="{y_low:.1f}" x2="{x+cap}" y2="{y_low:.1f}" stroke="{color}" stroke-width="6"/>',
        ))
        if marker == "circle":
            lines.append(f'<circle cx="{x}" cy="{y_mean:.1f}" r="10" fill="{color}" stroke="#071326" stroke-width="2"/>')
        elif marker == "square":
            lines.append(f'<rect x="{x-10}" y="{y_mean-10:.1f}" width="20" height="20" rx="2" fill="{color}" stroke="#071326" stroke-width="2"/>')
        else:
            lines.append(f'<path d="M{x} {y_mean-12:.1f} L{x+12} {y_mean:.1f} L{x} {y_mean+12:.1f} L{x-12} {y_mean:.1f} Z" fill="{color}" stroke="#071326" stroke-width="2"/>')
        lines.append(f'<text x="{x}" y="{bottom+38}" fill="#f3f6ff" font-family="Arial,sans-serif" font-size="20" text-anchor="middle">{name}</text>')
    lines.extend((
        f'<text x="{(left+right)/2:.1f}" y="{bottom+81}" fill="#f3f6ff" font-family="Arial,sans-serif" font-size="19" text-anchor="middle">Thruster</text>',
        f'<text x="{30 if wide else 25}" y="{(top+bottom)/2:.1f}" fill="#f3f6ff" font-family="Arial,sans-serif" font-size="20" text-anchor="middle" transform="rotate(-90 {30 if wide else 25} {(top+bottom)/2:.1f})">Thrust (mN)</text>',
        f'<text x="{width/2}" y="{height-25}" fill="#ffc857" font-family="Arial,sans-serif" font-size="17" text-anchor="middle">Source graph visually digitized - estimates only - y axis begins at 608 mN</text>',
        '</svg>',
    ))
    return "\n".join(lines) + "\n"


def main():
    rows = read_rows()
    (ROOT / "mean-thrust-95ci.svg").write_text(make_svg(True, rows), encoding="utf-8")
    (ROOT / "mean-thrust-95ci-mobile.svg").write_text(make_svg(False, rows), encoding="utf-8")
    print("Wrote wide and phone SVGs from approximate visual readings; these are not raw data.")


if __name__ == "__main__":
    main()
