import json
import os
from pathlib import Path

ROOT = Path(".")
INPUT_JSON = ROOT / "results" / "row20_h0_attribution" / "row20_thin_slice_attribution.json"
OUTPUT_JSON = ROOT / "results" / "row20_h0_attribution" / "row20_SN_probe.json"
OUTPUT_REPORT = ROOT / "results" / "row20_h0_attribution" / "row20_SN_probe_REPORT.md"


def load_json(path):
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def find_block(data, tag):
    for block in data.get("blocks", []):
        if block.get("tag") == tag:
            return block
    raise ValueError(f"Block not found: {tag}")


def find_node(block, slice_name):
    for node in block.get("nodes", []):
        if node.get("slice") == slice_name:
            return node
    raise ValueError(f"Slice not found: {slice_name}")


def main():
    data = load_json(INPUT_JSON)

    sn = find_block(data, "SN")
    node = find_node(sn, "SN mu z=0.35")

    data_val = node["data"]
    theory_val = node["theory"]
    residual = node["residual_after_gate_handling"]
    sigma_diag = node["sigma_diag"]
    diag_pull = node["diag_pull_sigma"]
    chi2 = node["white_chi2_contribution"]

    required_shift = data_val - theory_val
    fractional_shift = required_shift / theory_val

    interpretation = []

    if abs(diag_pull) >= 2:
        interpretation.append(
            "SN z=0.35 is a moderate/high pull node contributing significantly to Row 20 stress."
        )

    if abs(fractional_shift) < 0.02:
        interpretation.append(
            "Required shift is small in magnitude → consistent with calibration/offset sensitivity."
        )

    interpretation.append(
        "This node is sensitive to distance-modulus calibration (M_B / ladder effects)."
    )

    result = {
        "signature": "ROW20_SN_PROBE_v1",
        "context": "DIAGNOSTIC_NON_GATING",
        "SN_node": {
            "slice": "SN mu z=0.35",
            "data": data_val,
            "theory": theory_val,
            "residual": residual,
            "sigma_diag": sigma_diag,
            "diag_pull_sigma": diag_pull,
            "white_chi2_contribution": chi2,
            "required_shift": required_shift,
            "fractional_shift": fractional_shift
        },
        "interpretation": interpretation,
        "verdict": (
            "SN_midpoint_calibration_sensitive; "
            "diagnostic only; no physics, thresholds, datasets, parameters, or verdict changes."
        )
    }

    OUTPUT_JSON.parent.mkdir(parents=True, exist_ok=True)

    with open(OUTPUT_JSON, "w", encoding="utf-8") as f:
        json.dump(result, f, indent=2)

    with open(OUTPUT_REPORT, "w", encoding="utf-8") as f:
        f.write("# UTFANSWF v21 — Row 20 SN z=0.35 Probe\n\n")
        f.write("**Context:** DIAGNOSTIC_NON_GATING\n\n")

        f.write("## SN node\n\n")
        f.write("| Quantity | Value |\n")
        f.write("|---|---:|\n")
        f.write(f"| data | {data_val:.6f} |\n")
        f.write(f"| theory | {theory_val:.6f} |\n")
        f.write(f"| residual | {residual:.6f} |\n")
        f.write(f"| sigma_diag | {sigma_diag:.6f} |\n")
        f.write(f"| diag pull | {diag_pull:.6f} |\n")
        f.write(f"| chi2 contribution | {chi2:.6f} |\n")
        f.write(f"| required shift | {required_shift:.6f} |\n")
        f.write(f"| fractional shift | {fractional_shift:.6e} |\n\n")

        f.write("## Interpretation\n\n")
        for line in interpretation:
            f.write(f"- {line}\n")

        f.write("\n## Verdict\n\n")
        f.write(result["verdict"] + "\n")

    print("Wrote:")
    print(os.path.abspath(OUTPUT_JSON))
    print(os.path.abspath(OUTPUT_REPORT))
    print()
    print("SN z=0.35 probe:")
    print(f"data={data_val}")
    print(f"theory={theory_val}")
    print(f"pull={diag_pull} sigma")
    print(f"fractional_shift={fractional_shift:.6e}")


if __name__ == "__main__":
    main()