#!/usr/bin/env python3
"""Draw the reference plates from /tmp/konapsys.json emitted by dynamics.mjs."""

from __future__ import annotations

import json
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt


def main():
    import subprocess

    subprocess.check_call(["node", "/workspace/simulation/export-run.mjs"])
    all_runs = json.loads(Path("/tmp/konapsys.json").read_text())
    out = Path("/workspace/public/simulation")
    out.mkdir(parents=True, exist_ok=True)

    ink = "#1c1915"
    muted = "#5c564c"
    oxide = "#7c2d2d"
    paper = "#f7f3ea"
    green = "#1f4d3a"
    plt.rcParams.update(
        {
            "font.family": "serif",
            "axes.edgecolor": ink,
            "axes.labelcolor": ink,
            "xtick.color": ink,
            "ytick.color": ink,
            "text.color": ink,
            "figure.facecolor": paper,
            "axes.facecolor": paper,
        }
    )

    def col(run, key):
        return [r[key] for r in run["rows"]]

    pathology = all_runs["pathology"]
    t = col(pathology, "i")
    ci = pathology["collapseI"]
    fig, ax = plt.subplots(figsize=(8.2, 4.6), dpi=160)
    ax.plot(t, col(pathology, "kt"), color=oxide, lw=1.7, label="K teleological / K max")
    ax.plot(t, col(pathology, "kg"), color=ink, lw=1.7, label="K granular")
    ax.fill_between(
        t,
        0,
        [0.025 + 0.30 * r for r in col(pathology, "rho")],
        color=oxide,
        alpha=0.13,
        linewidth=0,
        label="dead-band width",
    )
    if ci is not None:
        ax.axvline(ci, color=oxide, lw=0.8, ls="--")
        ax.text(min(ci + 4, 230), 0.90, "Konapsys", color=oxide, fontsize=9)
    ax.set_ylim(0, 1.05)
    ax.set_xlim(0, t[-1])
    ax.set_xlabel("institutional time")
    ax.set_ylabel("normalised gain")
    ax.set_title("Pathology: sensory dead-band against teleological saturation")
    ax.legend(frameon=False, fontsize=8, loc="center left")
    for sp in ("top", "right"):
        ax.spines[sp].set_visible(False)
    fig.tight_layout()
    fig.savefig(out / "fig1-dual-gain.png")
    plt.close()

    fig, ax = plt.subplots(figsize=(8.2, 4.8), dpi=160)
    colors = {"pathology": oxide, "rectification": muted, "diode": green}
    for name, run in all_runs.items():
        ax.plot(col(run, "rho"), col(run, "D"), color=colors[name], lw=1.6, label=name)
        cidx = run["collapseI"]
        if cidx is not None:
            ax.scatter([run["rows"][cidx]["rho"]], [run["rows"][cidx]["D"]], color=colors[name], s=36, zorder=3)
    ax.axhline(1.0, color=ink, lw=0.6, ls=":")
    ax.text(0.02, 1.025, "shear  D*", fontsize=8, color=muted)
    ax.set_xlabel("closure   ρ")
    ax.set_ylabel("orthogonal error debt   D")
    ax.set_title("Phase space of the Middle Term")
    ax.legend(frameon=False, fontsize=8)
    for sp in ("top", "right"):
        ax.spines[sp].set_visible(False)
    fig.tight_layout()
    fig.savefig(out / "fig2-phase.png")
    plt.close()

    fig, axes = plt.subplots(1, 2, figsize=(8.6, 4.4), dpi=160, sharey=True)
    for ax, name, title in (
        (axes[0], "pathology", "Shared accumulator"),
        (axes[1], "diode", "Partitioned ledgers"),
    ):
        run = all_runs[name]
        tt = col(run, "i")
        ax.plot(tt, col(run, "pEndo"), color=muted, lw=1.4, label="L endo")
        ax.plot(tt, col(run, "pExo"), color=ink, lw=1.6, label="L exo")
        ax.plot(tt, col(run, "D"), color=oxide, lw=1.5, label="debt D")
        ax.axhline(1.0, color=ink, lw=0.6, ls=":")
        if run["collapseI"] is not None:
            ax.axvline(run["collapseI"], color=oxide, lw=0.7, ls="--")
        ax.set_title(title, fontsize=11)
        ax.set_xlabel("institutional time")
        ax.set_xlim(0, tt[-1])
        for sp in ("top", "right"):
            ax.spines[sp].set_visible(False)
    axes[0].set_ylabel("pressure and debt    (threshold = 1)")
    axes[1].legend(frameon=False, fontsize=8, loc="upper left")
    fig.suptitle("Where the threshold is spent", fontsize=12)
    fig.tight_layout()
    fig.savefig(out / "fig3-ledgers.png")
    plt.close()
    print("wrote", out)


if __name__ == "__main__":
    main()
