"""Render the report figure from source observations and saved live parameters.

Usage: python render_figure.py Puromycin.csv live-result.json kinetics.png
Requires numpy, pandas, matplotlib. Does not call an LLM or refit the data.
"""
import argparse
import hashlib
import json
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("source", type=Path)
parser.add_argument("result", type=Path)
parser.add_argument("output", type=Path)
args = parser.parse_args()
source = args.source
for input_path in (source, args.result):
    if not input_path.is_file():
        parser.error(f"Input file not found: {input_path}")
if hashlib.sha256(source.read_bytes()).hexdigest() != "389be46927d2217b13d48b5b9ec56374007a87ea607c8e6f004c17683c427c70":
    parser.error("Input SHA-256 does not match the published Puromycin source. Download the original CSV linked in the article.")
data = pd.read_csv(source)
result = json.loads(args.result.read_text())
fits = []
for state in ("treated", "untreated"):
    matches = [fit for fit in result["fits"] if fit.get("dataset_label") == state and fit.get("model_name") == "Michaelis-Menten"]
    if len(matches) != 1:
        parser.error(f"Expected exactly one saved Michaelis-Menten fit for {state}; found {len(matches)}.")
    fits.append(matches[0])
fig, ax = plt.subplots(figsize=(9, 5.8), layout="constrained")
for fit, color, marker in zip(fits, ["#246b68", "#7561ad"], ["o", "s"]):
    state = fit["dataset_label"]
    observations = data[data.state == state]
    vmax = fit["parameters"]["vmax"]["value"]
    km = fit["parameters"]["km"]["value"]
    x = np.linspace(0, 1.12, 250)
    ax.scatter(observations.conc, observations.rate, label=state.capitalize() + " observations", color=color, marker=marker, s=42, alpha=.8)
    ax.plot(x, vmax*x/(km+x), color=color, linewidth=2, label=state.capitalize() + " live fit")
ax.set(xlabel="Substrate concentration (ppm)", ylabel="Reaction rate (counts/min/min)", title="Puromycin: separate Michaelis–Menten fits", xlim=(-.015, 1.15), ylim=(0, 225))
ax.spines[["top", "right"]].set_visible(False)
ax.grid(alpha=.15)
ax.legend(frameon=False, loc="lower right", fontsize=9)
fig.savefig(args.output, dpi=180)
