import json
import os
from pathlib import Path

ROOT = Path(".")

INPUT_MAIN = ROOT / "results" / "row20_h0_attribution" / "row20_thin_slice_attribution.json"
INPUT_MINIMAP = ROOT / "results" / "row20_h0_attribution" / "row20_joint_residual_minimap.json"

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


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


def sign(x):
    if x > 0:
        return "+"
    if x < 0:
        return "-"
    return "0"


def main():
    main_data = load(INPUT_MAIN)
    minimap = load(INPUT_MINIMAP)

    rv = minimap["residual_vector"]

    cmb = rv["CMB_ell_A"]["pull_sigma"]
    sn = rv["SN_z0_35_pivot"]["pull_sigma"]
    bao_h = rv["BAO_z0_706_H"]["pull_sigma"]
    bao_dm = rv["BAO_z0_706_D_M"]["pull_sigma"]
    sh0es = rv["SH0ES_overlay"]["pull_sigma"]

    # Expected layered geometry pattern:
    # early acoustic anchor and radial expansion should share sign;
    # late SN distance curvature and transverse BAO distance can oppose.
    tests = {
        "CMB_lA_and_BAO_H_same_sign": sign(cmb) == sign(bao_h),
        "SN_pivot_and_BAO_DM_same_sign": sign(sn) == sign(bao_dm),
        "CMB_lA_and_SN_pivot_opposite_sign": sign(cmb) != sign(sn),
        "BAO_H_and_BAO_DM_opposite_sign": sign(bao_h) != sign(bao_dm),
        "SH0ES_and_SN_same_sign": sign(sh0es) == sign(sn),
    }

    score = sum(1 for v in tests.values() if v)
    max_score = len(tests)

    interpretation = []

    interpretation.append(
        "This test checks whether the opposing residual signs form a coherent layered geometry pattern rather than random mismatch."
    )

    if tests["CMB_lA_and_BAO_H_same_sign"]:
        interpretation.append(
            "CMB ell_A and BAO H(z) share sign, linking early acoustic anchoring with radial expansion stress."
        )

    if tests["SN_pivot_and_BAO_DM_same_sign"]:
        interpretation.append(
            "SN midpoint pivot and BAO D_M share sign, linking late distance curvature with transverse distance stress."
        )

    if tests["CMB_lA_and_SN_pivot_opposite_sign"]:
        interpretation.append(
            "CMB ell_A and SN pivot oppose, matching the early-vs-late split expected in H0 tension."
        )

    if tests["BAO_H_and_BAO_DM_opposite_sign"]:
        interpretation.append(
            "BAO H and D_M oppose at z≈0.706, marking the bridge as radial/transverse split rather than one-direction drift."
        )

    if tests["SH0ES_and_SN_same_sign"]:
        interpretation.append(
            "SH0ES overlay has the same sign as the SN pivot, placing it on the late-distance side of the split."
        )

    if score == max_score:
        status = "layered_sign_pattern_confirmed"
        interpretation.append(
            "All sign-consistency checks pass: the residual pattern is structured and layered, not random."
        )
    elif score >= 3:
        status = "layered_sign_pattern_partial"
        interpretation.append(
            "Most sign-consistency checks pass: the residual pattern is partially structured but needs further validation."
        )
    else:
        status = "layered_sign_pattern_weak"
        interpretation.append(
            "Sign-consistency checks are weak: the residual pattern may not support a layered-geometry explanation."
        )

    result = {
        "signature": "ROW20_LAYERED_SIGN_CONSISTENCY_v1_NATIVE_DIAGNOSTIC",
        "context": "DIAGNOSTIC_NON_GATING",
        "rules": main_data.get("rules", {}),
        "residuals": {
            "CMB_ell_A": cmb,
            "SN_pivot": sn,
            "BAO_H_z0_706": bao_h,
            "BAO_D_M_z0_706": bao_dm,
            "SH0ES_overlay": sh0es,
        },
        "signs": {
            "CMB_ell_A": sign(cmb),
            "SN_pivot": sign(sn),
            "BAO_H_z0_706": sign(bao_h),
            "BAO_D_M_z0_706": sign(bao_dm),
            "SH0ES_overlay": sign(sh0es),
        },
        "tests": tests,
        "score": score,
        "max_score": max_score,
        "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 Layered Sign Consistency\n\n")
        f.write("**Context:** DIAGNOSTIC_NON_GATING. No physics, thresholds, datasets, parameters, or gate verdicts changed.\n\n")

        f.write("## Residual signs\n\n")
        f.write("| Node | Pull sigma | Sign |\n")
        f.write("|---|---:|---:|\n")
        for k, v in result["residuals"].items():
            f.write(f"| {k} | {v:.6f} | {result['signs'][k]} |\n")

        f.write("\n## Sign-consistency tests\n\n")
        f.write("| Test | Pass |\n")
        f.write("|---|---:|\n")
        for k, v in tests.items():
            f.write(f"| {k} | {v} |\n")

        f.write(f"\nScore: **{score}/{max_score}**\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("Layered sign consistency:")
    print(f"score={score}/{max_score}")
    print(f"verdict={status}")
    print(f"CMB ell_A sign={sign(cmb)}")
    print(f"SN pivot sign={sign(sn)}")
    print(f"BAO H sign={sign(bao_h)}")
    print(f"BAO D_M sign={sign(bao_dm)}")
    print(f"SH0ES sign={sign(sh0es)}")


if __name__ == "__main__":
    main()