import json
import math
import os
from pathlib import Path

ROOT = Path(".")

INPUT_BRIDGE = ROOT / "results" / "row20_h0_attribution" / "row20_coupled_bridge_test.json"
INPUT_MINIMAP = ROOT / "results" / "row20_h0_attribution" / "row20_joint_residual_minimap.json"
INPUT_SIGN = ROOT / "results" / "row20_h0_attribution" / "row20_layered_sign_consistency.json"

OUTPUT_JSON = ROOT / "results" / "row20_h0_attribution" / "row20_bridge_origin_probe.json"
OUTPUT_REPORT = ROOT / "results" / "row20_h0_attribution" / "row20_bridge_origin_probe.md"


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


def rel_err(a, b):
    if b == 0:
        return None
    return abs(a - b) / abs(b)


def main():
    bridge = load(INPUT_BRIDGE)
    minimap = load(INPUT_MINIMAP)
    sign_data = load(INPUT_SIGN)

    best = bridge["best_no_flip_bridge"]
    b = best["bridge_strength"]

    residuals = sign_data["residuals"]

    cmb = residuals["CMB_ell_A"]
    bao_h = residuals["BAO_H_z0_706"]
    bao_dm = residuals["BAO_D_M_z0_706"]
    sn = residuals["SN_pivot"]
    sh0es = residuals["SH0ES_overlay"]

    bao_gap = minimap["coupling_tests"]["BAO_H_minus_DM_gap_sigma"]

    candidates = {
        "half_BAO_H_minus_DM_gap": abs(bao_gap) / 2.0,
        "BAO_H_pull": abs(bao_h),
        "BAO_DM_pull": abs(bao_dm),
        "mean_BAO_abs_pull": (abs(bao_h) + abs(bao_dm)) / 2.0,
        "SN_pivot_half_abs": abs(sn) / 2.0,
        "ell_A_minus_BAO_H_gap_half": abs(cmb - bao_h) / 2.0,
        "SH0ES_minus_SN_gap_half": abs(sh0es - sn) / 2.0,
    }

    comparisons = []
    for name, value in candidates.items():
        comparisons.append({
            "candidate": name,
            "value": value,
            "bridge_strength": b,
            "absolute_difference": abs(b - value),
            "relative_error": rel_err(b, value),
        })

    comparisons = sorted(comparisons, key=lambda x: x["absolute_difference"])

    best_match = comparisons[0]

    interpretation = []

    interpretation.append(
        "This probe tests whether the best coupled bridge strength can be attributed to an existing residual geometry scale rather than treated as a new fitted parameter."
    )

    if best_match["candidate"] in [
        "half_BAO_H_minus_DM_gap",
        "BAO_DM_pull",
        "mean_BAO_abs_pull",
        "BAO_H_pull",
    ]:
        interpretation.append(
            "The bridge strength is closest to a BAO bridge/projection scale, supporting a BAO-origin interpretation."
        )
    else:
        interpretation.append(
            "The bridge strength is closest to a non-BAO scale; BAO-origin is not yet preferred."
        )

    if best_match["relative_error"] is not None and best_match["relative_error"] < 0.20:
        interpretation.append(
            "The closest scale matches the bridge strength within 20%, which is sufficient for diagnostic-origin plausibility but not final proof."
        )
        status = "bridge_origin_plausibly_BAO_geometry"
    else:
        interpretation.append(
            "No candidate scale matches the bridge strength closely enough for origin attribution."
        )
        status = "bridge_origin_not_yet_attributed"

    result = {
        "signature": "ROW20_BRIDGE_ORIGIN_PROBE_v1_NATIVE_DIAGNOSTIC",
        "context": "DIAGNOSTIC_NON_GATING",
        "bridge_strength": b,
        "candidate_scales": candidates,
        "comparisons_ranked": comparisons,
        "best_match": best_match,
        "interpretation": interpretation,
        "verdict": (
            f"{status}; diagnostic only; no physics, thresholds, datasets, "
            "parameters, or gate verdicts changed."
        ),
    }

    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 Bridge Origin Probe\n\n")
        f.write("**Context:** DIAGNOSTIC_NON_GATING. No physics, thresholds, datasets, parameters, or gate verdicts changed.\n\n")

        f.write("## Bridge strength\n\n")
        f.write("| Quantity | Value |\n")
        f.write("|---|---:|\n")
        f.write(f"| best coupled bridge strength | {b:.6f} |\n\n")

        f.write("## Candidate origin scales\n\n")
        f.write("| Rank | Candidate | Value | abs difference | relative error |\n")
        f.write("|---:|---|---:|---:|---:|\n")
        for i, c in enumerate(comparisons, start=1):
            re = c["relative_error"]
            re_txt = "NA" if re is None else f"{re:.6f}"
            f.write(
                f"| {i} | {c['candidate']} | {c['value']:.6f} | "
                f"{c['absolute_difference']:.6f} | {re_txt} |\n"
            )

        f.write("\n## Best match\n\n")
        f.write("```json\n")
        f.write(json.dumps(best_match, indent=2))
        f.write("\n```\n\n")

        f.write("## Interpretation\n\n")
        for item in interpretation:
            f.write(f"- {item}\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("Bridge origin probe:")
    print(f"bridge strength={b:.6f}")
    print(f"best match={best_match['candidate']}")
    print(f"match value={best_match['value']:.6f}")
    print(f"relative error={best_match['relative_error']:.6f}")
    print(f"verdict={status}")


if __name__ == "__main__":
    main()