#!/usr/bin/env python3
"""Render measured quarterly timing-derived angles; standard library only."""
from pathlib import Path
import argparse, json, html


def figure(data):
    width, height = 340, 560
    left, right = 56, 326
    rows = data["bins"]
    times = [row["representativeBjdOffset"] for row in rows]
    minimum, maximum = min(times), max(times)
    parts = [
        f'<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" viewBox="0 0 {width} {height}" role="img"><title>Measured Kepler-223 quarterly timing diagnostic</title><rect width="100%" height="100%" fill="#091226"/>'
    ]

    def label(x, y, text, anchor="start", colour="#c9d9ec", size=13):
        parts.append(
            f'<text x="{x:.3f}" y="{y:.3f}" text-anchor="{anchor}" fill="{colour}" font-family="system-ui,sans-serif" font-size="{size}">{html.escape(str(text))}</text>'
        )

    label(left, 27, "Kepler-223 timing angles", size=15)
    for index, (name, title, colour) in enumerate(
        [
            ("inner", "Inner triplet (degrees)", "#ffca76"),
            ("outer", "Outer triplet (degrees)", "#67e8f9"),
        ]
    ):
        top = 64 + index * 218
        bottom = top + 150
        low = (
            min(
                row["angles"][name]["degrees"]
                + row["angles"][name]["deltaChiSquareOneRectangleOffsetsDegrees"][0]
                for row in rows
            )
            - 3
        )
        high = (
            max(
                row["angles"][name]["degrees"]
                + row["angles"][name]["deltaChiSquareOneRectangleOffsetsDegrees"][1]
                for row in rows
            )
            + 3
        )
        x = lambda value: left + (value - minimum) / (maximum - minimum) * (
            right - left
        )
        y = lambda value: bottom - (value - low) / (high - low) * (bottom - top)
        label(left, top - 15, title, colour=colour)
        for tick in range(4):
            value = low + (high - low) * tick / 3
            position = y(value)
            parts.append(
                f'<path d="M {left} {position:.3f} H {right}" fill="none" stroke="#7890ad44"/>'
            )
            label(left - 10, position + 4, f"{value:.1f}", "end")
        for row in rows:
            angle = row["angles"][name]
            px = x(row["representativeBjdOffset"])
            py = y(angle["degrees"])
            bounds = angle["deltaChiSquareOneRectangleOffsetsDegrees"]
            parts.append(
                f'<path d="M {px:.3f} {y(angle["degrees"]+bounds[0]):.3f} V {y(angle["degrees"]+bounds[1]):.3f}" stroke="{colour}" stroke-width="2"/><circle cx="{px:.3f}" cy="{py:.3f}" r="3.4" fill="{colour}"/>'
            )
        for tick in range(4):
            value = minimum + (maximum - minimum) * tick / 3
            label(
                x(value),
                bottom + 24,
                f"{value:.0f}",
                "start" if tick == 0 else "end" if tick == 3 else "middle",
            )
    label(left, 508, "Published BJD minus 2454900")
    label(left, 532, "Bars: individual profile-interval rectangles.", size=11)
    label(left, 551, "Mills et al. 2016, ED Table 1; own calculation.", size=10)
    return "".join(parts) + "</svg>\n"


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--input", type=Path, default=Path("kepler223-angles.json"))
    parser.add_argument("--output", type=Path, default=Path("kepler223-angles.svg"))
    args = parser.parse_args()
    args.output.write_text(figure(json.loads(args.input.read_text())))


if __name__ == "__main__":
    main()
