"""Validation harness proof — quantitative segmentation + trajectory metrics.

Shows the evidence pipeline a surgeon/IRB expects: segment a clot with the
classical method, score it against ground truth (Dice, Hausdorff-95, ASSD,
volume error), and report trajectory error vs a reference. Emits a figure and a
JSON metrics report.

RESEARCH SOFTWARE — NOT FOR CLINICAL USE.
"""
import os, sys, json
import numpy as np
import matplotlib; matplotlib.use("Agg")
import matplotlib.pyplot as plt

HERE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, HERE)
from sulcora.volume import Volume
from sulcora.planning import Trajectory
from sulcora import hematoma as H, validate as V


def main():
    docs = os.path.join(HERE, "docs", "images"); os.makedirs(docs, exist_ok=True)
    shape = (80, 80, 80)
    ii, jj, kk = np.meshgrid(*[np.arange(s) for s in shape], indexing="ij")
    c = np.array([46, 40, 40]); rng = np.random.default_rng(0)
    # ground-truth clot (ellipsoid) in a noisy CT
    truth = (((ii - c[0]) / 10.0) ** 2 + ((jj - c[1]) / 7.0) ** 2 + ((kk - c[2]) / 7.0) ** 2) <= 1
    ct = (30 + rng.normal(0, 6, shape)).astype(np.float32)
    ct[truth] = 70 + rng.normal(0, 6, truth.sum())
    vol = Volume(ct, np.eye(4)); truth_v = Volume(truth.astype(np.uint8), np.eye(4))

    pred = H.segment_hematoma(vol, hu_lo=45, hu_hi=100, keep_largest=True)
    seg = V.segmentation_metrics(pred, truth_v)
    print("segmentation:", json.dumps(seg, indent=2))

    # trajectory: reference vs a slightly-off plan
    ref = Trajectory(np.array([70, 40, 40.0]), c.astype(float))
    plan = Trajectory(np.array([70, 43, 41.0]), c.astype(float) + np.array([1.0, 0, 0]))
    traj = V.trajectory_error(plan, ref)
    print("trajectory:", json.dumps(traj, indent=2))

    report = {"segmentation": seg, "trajectory": traj}
    with open(os.path.join(docs, "validation_report.json"), "w") as f:
        json.dump(report, f, indent=2)

    z = int(c[2])
    fig, ax = plt.subplots(1, 2, figsize=(10, 5), facecolor="#0b0f18")
    a = ax[0]
    a.imshow(Volume(ct, np.eye(4)).window().data[:, :, z].T, cmap="gray", origin="lower")
    tr = np.ma.masked_where(~truth[:, :, z], truth[:, :, z]).T
    pr = np.ma.masked_where(pred.data[:, :, z] == 0, pred.data[:, :, z]).T
    a.imshow(tr, cmap="Greens", alpha=0.5, origin="lower")
    a.imshow(pr, cmap="autumn", alpha=0.45, origin="lower")
    a.set_title("green = ground truth · red = segmentation", color="#9fd0ff", fontsize=10); a.axis("off")

    ax[1].axis("off")
    rows = [("Dice", f"{seg['dice']:.3f}"), ("Jaccard", f"{seg['jaccard']:.3f}"),
            ("Hausdorff-95", f"{seg['hausdorff95_mm']:.2f} mm"), ("ASSD", f"{seg['assd_mm']:.2f} mm"),
            ("Volume err", f"{seg['volume_error_cc']:+.2f} cc ({seg['abs_volume_error_pct']:.1f}%)"),
            ("Entry error", f"{traj['entry_error_mm']:.2f} mm"),
            ("Target error", f"{traj['target_error_mm']:.2f} mm"),
            ("Angle error", f"{traj['angle_error_deg']:.2f}°")]
    y = 0.92
    ax[1].text(0.0, 0.99, "Validation metrics", color="#dce6f5", fontsize=13, weight="bold", transform=ax[1].transAxes)
    for k, v in rows:
        ax[1].text(0.0, y, k, color="#8aa0c0", fontsize=11, transform=ax[1].transAxes)
        ax[1].text(0.55, y, v, color="#e8f0ff", fontsize=11, weight="bold", transform=ax[1].transAxes)
        y -= 0.11
    fig.suptitle("Sulcora validation harness — segmentation & trajectory accuracy",
                 color="#dce6f5", fontsize=13)
    fig.text(0.5, 0.02, "RESEARCH SOFTWARE — NOT FOR CLINICAL USE.", color="#c0392b", ha="center", fontsize=9)
    fig.tight_layout(rect=[0, 0.04, 1, 0.95])
    out = os.path.join(docs, "validation_metrics.png")
    fig.savefig(out, dpi=130, facecolor=fig.get_facecolor()); plt.close(fig)
    print("wrote", out, "\nVALIDATION PROOF OK")


if __name__ == "__main__":
    main()
